大数据知识体系
首页
数据结构与算法
  • JVM
  • Java
  • Scala
  • Python
设计模式
  • MySQL
  • Redis
  • HDFS
  • HBase
  • ClickHouse
  • ElasticSearch
  • Iceberg
  • Hudi
  • Spark
  • Flink
  • Hive
  • Yarn
  • Zookeeper
  • Maven
  • Git
  • 数据仓库
  • 用户画像
  • 指标体系
数据治理
关于
首页
数据结构与算法
  • JVM
  • Java
  • Scala
  • Python
设计模式
  • MySQL
  • Redis
  • HDFS
  • HBase
  • ClickHouse
  • ElasticSearch
  • Iceberg
  • Hudi
  • Spark
  • Flink
  • Hive
  • Yarn
  • Zookeeper
  • Maven
  • Git
  • 数据仓库
  • 用户画像
  • 指标体系
数据治理
关于
  • JVM

    • JVM 架构
    • JVM 类加载机制
    • JVM 运行时数据区
    • JVM 垃圾回收机制
    • JVM 性能监控与调优
    • JVM 常见错误
  • Java

    • Java基础

      • Java 基础知识
      • Java 基础 - 枚举类
      • Java 基础 - 异常处理
      • Java 基础 - 泛型
      • Java 基础 - 反射
      • Java 基础 - 代理模式
      • Java 基础 - 注解
    • Java集合

    • Java并发编程

    • Java 开发规范
  • Scala

    • Scala 概述
  • Python

    • Numpy

      • 初识 Numpy
      • ndarray 的创建方式
      • NumPy 的数据类型
      • NumPy 数组计算
      • 拷贝
      • 索引和切片
      • 数学和统计方法
      • 数组形状变换
      • 通用函数
      • 排序
      • 搜索和计数
      • 线性代数
      • 伪随机数生成
      • 广播
      • 文件输入和输出
    • Pandas

      • 初识 Pandas
      • 认识 Series 和 DataFrame
      • Series 和 DataFrame 增删改查
      • Index对象增删改查
      • 普通列和行Index相互转化
      • 快速查看整体信息
      • 数值运算
      • 合并数据集
      • 数值统计与聚合
      • 分组聚合
      • 分类类型
        • 创建
          • 创建 Category 的类
          • 转换为类别类型
        • 查、改、增、删
          • 查
          • 改
          • 有序、无序转变
          • 有序改变顺序
          • 增
          • 删
          • 删除任意不需要的类别
          • 去除没有使用的类别
          • 改增删三合一
        • cut() 和 qcut()
          • cut()
          • qcut()
      • 排序和排名
      • 时间序列
      • 文件输入与输出
      • 缺失值处理
      • 字符串处理
      • pandas sql
      • 其它
  • 语言基础
  • Python
  • Pandas
Will
2022-08-04
目录

分类类型

类别类型可谓是非常常用的一种类型,其具有如下特征:

  1. 取固定几种值;
  2. 可以定义序,序的形式与实数序或字典序可以都不同;
  3. 即使是数值表示,数值运算可能也无意义,与离散数值型不一定相同。
import numpy as np
import pandas as pd
1
2

# 创建

# 创建 Category 的类

pd.Categorical(values, categories=None, ordered=False)

  • values: 类别序列;
  • categories:自定义的类别序列;
  • ordered:类别是否定义顺序,默认增序。
c = pd.Categorical([2,1,1,3], ordered = True )
c
# 不提供categories,则用values去重后的值作为类别
# 若ordered = True,顺序则按照字典序升序给定
1
2
3
4
[2, 1, 1, 3]
Categories (3, int64): [1 < 2 < 3]
c = pd.Categorical([1,2,3], categories = [3,2], ordered = True )
c
# 提供 categories(类别不能有重复,否则报错),若values的值不在categories中,则用NaN替换
# 若ordered = True,顺序则按照类别顺序升序给定
1
2
3
4
[NaN, 2, 3]
Categories (2, int64): [3 < 2]

类别的两个重要属性

c.categories  # 类别
1
Int64Index([3, 2], dtype='int64')
c.ordered # 是否有序
1
True
# 创建分类的 Series
pd.Series(c)
1
2
0    NaN
1      2
2      3
dtype: category
Categories (2, int64): [3 < 2]
# 需要注意的是:Categories必须是unique,并且不能为NaN,否则会报ValueError
try:
    # c.categories = [1, 1]
    c.categories = [1, np.NaN]
except ValueError as e:
    print(e)
1
2
3
4
5
6
Categorical categories cannot be null

# 转换为类别类型

s = pd.Series([2,1,1,3], dtype='category') # 当然也可以通过 astype('category') 将其它 Series 或 DataFrame 进行转换
s
1
2
0    2
1    1
2    1
3    3
dtype: category
Categories (3, int64): [1, 2, 3]

Series 查看类型属性需要通过.cat

s.cat.categories
1
Int64Index([1, 2, 3], dtype='int64')
s.cat.ordered
1
False

# 查、改、增、删

# 查

[] 四种查看方式

类别类型是序列形式,可以采用[]来查看,不过.loc[]和.iloc[]都是不支持的。

c[0]
1
nan
c[0:2]
1
[NaN, 2]
Categories (2, int64): [3 < 2]
c[[0,2]]
1
[NaN, 3]
Categories (2, int64): [3 < 2]
mask = [True, False, True]
c[mask]
1
2
[NaN, 3]
Categories (2, int64): [3 < 2]

# 改

改类别值这个功能用得会比较多,将字符串类别映射为数值类别。

直接修改

c1 = c.copy()
1
c1.categories = ['5','6']   # 这种改法,新的类别序列与旧类别序列长度必须相同,实质为将值和类型依次替换
c1
1
2
[NaN, '6', '5']
Categories (2, object): ['5' < '6']
s1= s.copy()
s1
1
2
0    2
1    1
2    1
3    3
dtype: category
Categories (3, int64): [1, 2, 3]
s1.cat.categories = [6,5,7]
s1 # 对Series来说,用.cat操作改法是相同的
1
2
0    5
1    6
2    6
3    7
dtype: category
Categories (3, int64): [6, 5, 7]

函数改

categories.rename_categories(cat , inplace=False)

  • cat:新的类别,必须和旧类别长度相同;
  • inplace:True or False,是否原地修改。
c1 = c.copy()
c1.rename_categories(['5','6'], inplace=True)  #和上面完全相同
c1
1
2
3
[NaN, '6', '5']
Categories (2, object): ['5' < '6']
s1 = s.copy()
s1.cat.rename_categories(['6','5','7'], inplace=True) # 和上面完全相同
s1
1
2
3
0    5
1    6
2    6
3    7
dtype: category
Categories (3, object): ['6', '5', '7']
# 也可以传入一个字典
c1.rename_categories({'5': 'a', '6':'b'})
1
2
[NaN, 'b', 'a']
Categories (2, object): ['a' < 'b']
# 通过传入一个字典
s1.cat.rename_categories({'5':'A', '6':'B', '7':'C'})
1
2
0    A
1    B
2    B
3    C
dtype: category
Categories (3, object): ['B', 'A', 'C']

# 有序、无序转变

categories.as_ordered(inplace = False)

categories.as_unordered(inplace = False)

  • inplace:True or False,是否原地修改。
c1 = c.copy()
c1
1
2
[NaN, 2, 3]
Categories (2, int64): [3 < 2]
c1.as_unordered(inplace = True)
c1
1
2
[NaN, 2, 3]
Categories (2, int64): [3, 2]
c1.as_ordered()
1
[NaN, 2, 3]
Categories (2, int64): [3 < 2]

# 有序改变顺序

categories.reorder_categories(cat , ordered = False,inplace = False)

  • cat:只能是旧类别改变顺序后的序列,不能增减类别;
  • ordered:True or False,类别是否有序
  • inplace:True or False,是否原地修改。
c1 = c.copy()
c1
1
2
[NaN, 2, 3]
Categories (2, int64): [3 < 2]
c1.reorder_categories([2,3],ordered = True,inplace = True)
c1
1
2
[NaN, 2, 3]
Categories (2, int64): [2 < 3]

# 增

categories.add_categories(cat,inplace = False)

  • cat:想要新增的类别,必须不在旧类别中;
  • inplace:True or False,是否原地修改。
c1 = c.copy()
c1
1
2
[NaN, 2, 3]
Categories (2, int64): [3 < 2]
c1.add_categories([4,5], inplace = True)
c1
1
2
[NaN, 2, 3]
Categories (4, int64): [3 < 2 < 4 < 5]

# 删

# 删除任意不需要的类别

categories.remove_categories(cat,inplace = False)

  • cat:想要删除的类别,必须在旧类别中;
  • inplace:True or False,是否原地修改。
c1.remove_categories([4],inplace = True)
c1
1
2
[NaN, 2, 3]
Categories (3, int64): [3 < 2 < 5]

# 去除没有使用的类别

categories.remove_unused_categories(inplace = False)

  • inplace:True or False,是否原地修改。
c1.remove_unused_categories(inplace=True)  # 类别 5 被去除
c1
1
2
[NaN, 2, 3]
Categories (2, int64): [3 < 2]

# 改增删三合一

categories.set_categories(cat , ordered=False,rename=False, inplace=False)

  • cat:只能是旧类别改变顺序后的序列,不能增减类别;
  • ordered:True or False,改序,如果提供这一项,保持原来属性,最好明确给出;
  • rename:True or False,改名,这个参数我发现没啥用(?);
  • inplace:True or False,是否原地修改。
c1 = c.copy()
c1
1
2
[NaN, 2, 3]
Categories (2, int64): [3 < 2]
c1.set_categories([2,4,5], ordered = True, inplace = True) # 删除了旧类别 1,增加新类别4、5,
c1
1
2
[NaN, 2, NaN]
Categories (3, int64): [2 < 4 < 5]

# cut() 和 qcut()

这俩函数用于将连续型变量分割为类别变量。

# cut()

pd.cut(x, bins, right = False,include_lowest=False, labels=None, retbins=False)

  • x:待分割的 Series 或序列;
  • bins:如果是 int,那么将 Series 的进行等分,并在最大最小值的基础上外延 1%作为区间边界;如果是序列,那么将序列值作为分隔点;
  • right:True or False,分隔区间默认为左闭右开;
  • include_lowest:True or False,将最左侧区间的左值外延 1%,试图去包含最小值;
  • labels:分隔后是区间,可以用 label 来替换为想要的类别形式;
  • retbins:是否返回分隔点;
s = pd.Series( range(0,5))
s
1
2
0    0
1    1
2    2
3    3
4    4
dtype: int64
pd.cut( s, 3)   # 可以看到一共3个类别,类别形式为区间形式(]
1
0    (-0.004, 1.333]
1    (-0.004, 1.333]
2     (1.333, 2.667]
3       (2.667, 4.0]
4       (2.667, 4.0]
dtype: category
Categories (3, interval[float64]): [(-0.004, 1.333] < (1.333, 2.667] < (2.667, 4.0]]
pd.cut( s, 3, labels = ['a','b','c'])   # 这样就清晰多了
1
0    a
1    a
2    b
3    c
4    c
dtype: category
Categories (3, object): ['a' < 'b' < 'c']
pd.cut( s, 3, labels = ['a','b','c'], retbins = True)   # 分隔点也返回
1
(0    a
 1    a
 2    b
 3    c
 4    c
 dtype: category
 Categories (3, object): ['a' < 'b' < 'c'],
 array([-0.004     ,  1.33333333,  2.66666667,  4.        ]))
pd.cut(s,[0,2.5,4], right = False)  # 左闭右开,不包括4,所以4不属于任何一类别
1
0    [0.0, 2.5)
1    [0.0, 2.5)
2    [0.0, 2.5)
3    [2.5, 4.0)
4           NaN
dtype: category
Categories (2, interval[float64]): [[0.0, 2.5) < [2.5, 4.0)]
pd.cut(s,[0,2.5,4], right = True)  # 左开右闭,不包括0,所以0不属于任何一类别
1
0           NaN
1    (0.0, 2.5]
2    (0.0, 2.5]
3    (2.5, 4.0]
4    (2.5, 4.0]
dtype: category
Categories (2, interval[float64]): [(0.0, 2.5] < (2.5, 4.0]]
pd.cut(s,[0,2.5,4], right = True, include_lowest = True)  # 最左侧值被包含
1
0    (-0.001, 2.5]
1    (-0.001, 2.5]
2    (-0.001, 2.5]
3       (2.5, 4.0]
4       (2.5, 4.0]
dtype: category
Categories (2, interval[float64]): [(-0.001, 2.5] < (2.5, 4.0]]

# qcut()

pd.qcut(x, q, labels=None, retbins=False)

  • x:待分割的 Series 或序列;
  • q:安装分位数也来定义分隔点,而不是按照给定值;
  • labels:分隔后是区间,可以用 label 来替换为想要的类别形式;
  • retbins:是否返回分隔点;
pd.qcut(s, q = [0.0, 0.25, 0.5,0.75, 1.0], labels =['a','b','c','d'])
# 5个分位点,形成 4 个区间。看来默认参数是right =True, include_lowest = True
1
2
0    a
1    a
2    b
3    c
4    d
dtype: category
Categories (4, object): ['a' < 'b' < 'c' < 'd']
上次更新: 2023/11/01, 03:11:44

← 分组聚合 排序和排名→

Theme by Vdoing | Copyright © 2022-2023 Will 蜀ICP备2022002285号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式