分类数据通过 .cat 访问器提供类别管理与编码信息。本节介绍 categories、ordered、codes 等核心属性。


1. .cat 访问器

用于分类数据的访问器,类似 .str 与 .dt:

s = pd.Series(['a', 'b', 'a']).astype('category')
s.cat
# <pandas.core.arrays.categorical.CategoricalAccessor object at ...>

只有 dtype 为 category 的 Series 才可以使用 .cat。普通 object 列不能使用。


2. categories 属性

返回类别的 Index。

s = pd.Series(['低', '中', '高', '低']).astype('category')
s.cat.categories
# Index(['低', '中', '高'], dtype='object')

categories 的特征

  • 是 Index 对象,支持 Index 方法(reorder、rename 等)
  • 默认按首次出现的顺序(astype 时)或按 pd.Categorical 指定的顺序
  • 可通过 Index 方法进行直接操作

3. ordered 属性

表示分类是否有顺序。

s = pd.Series(['低', '高']).astype(
    pd.CategoricalDtype(categories=['低', '中', '高'], ordered=True)
)
s.cat.ordered   # True
 
# 无序分类
s2 = pd.Series(['低', '高']).astype('category')
s2.cat.ordered  # False

影响

  • 有序分类支持 <、>、min、max 等比较运算
  • 无序分类只能做相等比较

4. codes 属性

返回底层整数编码(从 0 开始对应 categories)。

s = pd.Series(['乙', '丙', '甲']).astype(
    pd.CategoricalDtype(categories=['甲', '乙', '丙'])
)
 
s.cat.codes
# 0    1
# 1    2
# 2    0
# dtype: int8

与 categories 的关系

codes = s.cat.codes
categories = s.cat.categories
result = categories[codes]
# Index(['乙', '丙', '甲'], dtype='object')

codes 的 dtype

  • codes 的类型通常是 int8,因为 pandas 内部使用 8 位整数
  • 缺失值对应的 codes 为 -1

5. 缺失值处理

分类数据中的缺失值:

s = pd.Series(['a', None, 'b']).astype('category')
print(s)
# 0      a
# 1    NaN
# 2      b
# Categories (2, object): ['a', 'b']
 
# isna 正常判断
s.isna()
# 0    False
# 1     True
# 2    False
 
# codes 中对应 -1
s.cat.codes
# 0    0
# 1   -1
# 2    1
# dtype: int8

注意

分类数据中的缺失值通常显示为 NaN,但其底层使用 -1 编码。


6. 其他属性

属性说明
s.dtype返回 CategoricalDtype 对象
s.dtype.categories类别
s.dtype.ordered是否有序
s.array底层的 Categorical 对象
s.value_counts()各类别频次(会包含未使用的类别,与普通 Series 不同)
s = pd.Series(['a', 'b', 'a']).astype(
    pd.CategoricalDtype(categories=['a', 'b', 'c'])
)
s.value_counts()
# a    2
# b    1
# c    0
# Name: count, dtype: int64

value_counts 特殊行为

分类列的 value_counts() 默认会将所有类别(即使未出现)都统计为 0。可通过 dropna=True/False 控制缺失值是否统计。


7. 查看类别与数据交互

df = pd.DataFrame({'等级': ['高', '低', '中', '高']})
df['等级'] = df['等级'].astype('category')
 
# 筛选特定类别
df[df['等级'].isin(['高', '中'])]
 
# 类别计数
df['等级'].value_counts()
 
# 转回列表
df['等级'].cat.categories.tolist()
 
# 判断是否有重复
df['等级'].duplicated()

小结

  • .cat 访问器是分类数据的核心接口
  • categories 提供类别集合
  • ordered 决定是否支持顺序比较
  • codes 暴露底层编码
  • 缺失值编码为 -1
  • value_counts() 包含未使用类别