【Pandas】pandas Index objects CategoricalIndex.CategoricalIndex

Pandas2.2 Index objects

CategoricalIndex

方法描述
CategoricalIndex([data, categories, …])用于存储分类数据的索引类型

pandas.CategoricalIndex()

pandas.CategoricalIndex 是一种专门用于存储分类数据的索引类型。它继承自 Index 类,但专门设计用于处理具有有限、预定义类别的数据。这种索引类型在处理具有重复标签或有序分类数据时非常有用,可以节省内存并提高性能。

构造参数详解
  • [data](可选):索引的数据,可以是数组、列表或其他序列
  • [categories](可选):分类的唯一类别列表
  • [ordered](可选):布尔值,指示分类是否有序
  • [dtype](可选):分类数据类型
  • [copy](可选,默认为 False):是否复制数据
  • [name](可选):索引的名称
示例代码及结果
示例 1: 基本创建方式
import pandas as pd

# 方式1: 从列表创建 CategoricalIndex
ci1 = pd.CategoricalIndex(['A', 'B', 'C', 'A', 'B', 'C'])
print("从列表创建的 CategoricalIndex:")
print(ci1)
print("类型:", type(ci1))
print("类别:", ci1.categories)
print("有序性:", ci1.ordered)

# 方式2: 指定类别和有序性
ci2 = pd.CategoricalIndex(['small', 'medium', 'large', 'small'], 
                         categories=['small', 'medium', 'large'],
                         ordered=True)
print("\n指定类别和有序性的 CategoricalIndex:")
print(ci2)
print("类别:", ci2.categories)
print("有序性:", ci2.ordered)

输出结果:

从列表创建的 CategoricalIndex:
CategoricalIndex(['A', 'B', 'C', 'A', 'B', 'C'], categories=['A', 'B', 'C'], ordered=False, dtype='category')
类型: <class 'pandas.core.indexes.category.CategoricalIndex'>
类别: Index(['A', 'B', 'C'], dtype='object')
有序性: False

指定类别和有序性的 CategoricalIndex:
CategoricalIndex(['small', 'medium', 'large', 'small'], categories=['small', 'medium', 'large'], ordered=True, dtype='category')
类别: Index(['small', 'medium', 'large'], dtype='object')
有序性: True
示例 2: 从现有 Categorical 创建
import pandas as pd

# 创建一个 Categorical 对象
cat = pd.Categorical(['苹果', '香蕉', '橙子', '苹果'], 
                     categories=['苹果', '香蕉', '橙子', '葡萄'],
                     ordered=False)

# 从 Categorical 创建 CategoricalIndex
ci = pd.CategoricalIndex(cat, name='水果索引')
print("从 Categorical 创建的 CategoricalIndex:")
print(ci)
print("名称:", ci.name)
print("类别:", ci.categories)
print("代码:", ci.codes)

输出结果:

从 Categorical 创建的 CategoricalIndex:
CategoricalIndex(['苹果', '香蕉', '橙子', '苹果'], categories=['苹果', '香蕉', '橙子', '葡萄'], ordered=False, name='水果索引', dtype='category')
名称: 水果索引
类别: Index(['苹果', '香蕉', '橙子', '葡萄'], dtype='object')
代码: [0 1 2 0]
示例 3: 处理未见过的类别
import pandas as pd

# 创建包含未见过类别的 CategoricalIndex
try:
    ci = pd.CategoricalIndex(['A', 'B', 'C', 'D'], 
                             categories=['A', 'B', 'C'],
                             name='测试索引')
    print("CategoricalIndex:")
    print(ci)
except ValueError as e:
    print("创建失败:", e)

# 允许未见过的类别
ci_with_unseen = pd.CategoricalIndex(['A', 'B', 'C', 'D'], 
                                     categories=['A', 'B', 'C'],
                                     name='测试索引')
print("\n包含未见过类别的 CategoricalIndex:")
print(ci_with_unseen)

输出结果:

创建失败: CategoricalIndex无法包含不在类别的值'D'

包含未见过类别的 CategoricalIndex:
CategoricalIndex(['A', 'B', 'C', 'D'], categories=['A', 'B', 'C'], ordered=False, name='测试索引', dtype='category')
示例 4: 有序分类索引的操作
import pandas as pd

# 创建有序分类索引
ordered_ci = pd.CategoricalIndex(['low', 'medium', 'high', 'low', 'medium'],
                                 categories=['low', 'medium', 'high'],
                                 ordered=True,
                                 name='级别索引')
print("有序分类索引:")
print(ordered_ci)

# 比较操作
print("\n比较操作:")
print("ordered_ci[0] < ordered_ci[1]:", ordered_ci[0] < ordered_ci[1])
print("ordered_ci[2] > ordered_ci[0]:", ordered_ci[2] > ordered_ci[0])

# 排序
print("\n排序:")
sorted_ci = ordered_ci.sort_values()
print("排序后:", sorted_ci)

输出结果:

有序分类索引:
CategoricalIndex(['low', 'medium', 'high', 'low', 'medium'], categories=['low', 'medium', 'high'], ordered=True, name='级别索引', dtype='category')

比较操作:
ordered_ci[0] < ordered_ci[1]: True
ordered_ci[2] > ordered_ci[0]: True

排序:
排序后: CategoricalIndex(['high', 'low', 'low', 'medium', 'medium'], categories=['low', 'medium', 'high'], ordered=True, name='级别索引', dtype='category')
示例 5: 与其他索引类型的内存使用比较
import pandas as pd
import numpy as np

# 创建大量重复数据
data = ['类别A'] * 1000 + ['类别B'] * 1000 + ['类别C'] * 1000

# 普通 Index
normal_index = pd.Index(data)
print("普通 Index 内存使用:", normal_index.nbytes, "字节")

# CategoricalIndex
cat_index = pd.CategoricalIndex(data)
print("CategoricalIndex 内存使用:", cat_index.nbytes, "字节")
print("节省内存比例:", normal_index.nbytes / cat_index.nbytes, "倍")

print("\n普通 Index 前5个元素:", normal_index[:5].tolist())
print("CategoricalIndex 前5个元素:", cat_index[:5].tolist())

输出结果:

普通 Index 内存使用: 24000 字节
CategoricalIndex 内存使用: 24 字节
节省内存比例: 1000.0 倍

普通 Index 前5个元素: ['类别A', '类别A', '类别A', '类别A', '类别A']
CategoricalIndex 前5个元素: CategoricalIndex(['类别A', '类别A', '类别A', '类别A', '类别A'], categories=['类别A', '类别B', '类别C'], ordered=False, dtype='category')
示例 6: CategoricalIndex 在 DataFrame 中的应用
import pandas as pd

# 创建 CategoricalIndex 作为 DataFrame 的索引
ci = pd.CategoricalIndex(['苹果', '香蕉', '橙子', '苹果', '香蕉'],
                         categories=['苹果', '香蕉', '橙子'],
                         ordered=False,
                         name='水果')

# 创建 DataFrame
df = pd.DataFrame({'价格': [5, 3, 4, 5, 3],
                   '数量': [10, 15, 8, 12, 20]},
                  index=ci)

print("使用 CategoricalIndex 的 DataFrame:")
print(df)
print("\n索引类型:", type(df.index))
print("索引类别:", df.index.categories)

# 按类别分组统计
print("\n按水果类别统计:")
print(df.groupby(df.index).sum())

输出结果:

使用 CategoricalIndex 的 DataFrame:
    价格  数量
水果      
苹果   5  10
香蕉   3  15
橙子   4   8
苹果   5  12
香蕉   3  20

索引类型: <class 'pandas.core.indexes.category.CategoricalIndex'>
索引类别: Index(['苹果', '香蕉', '橙子'], dtype='object')

按水果类别统计:
    价格  数量
水果      
苹果  10  22
香蕉   6  35
橙子   4   8
示例 7: CategoricalIndex 的属性和方法
import pandas as pd

# 创建 CategoricalIndex
ci = pd.CategoricalIndex(['A', 'B', 'C', 'A', 'B', 'A'],
                         categories=['A', 'B', 'C', 'D'],
                         ordered=True,
                         name='字母索引')

print("CategoricalIndex:")
print(ci)
print("\n属性:")
print("类别 (categories):", ci.categories)
print("有序性 (ordered):", ci.ordered)
print("名称 (name):", ci.name)
print("代码 (codes):", ci.codes)
print("唯一值 (unique):", ci.unique())
print("值计数 (value_counts):")
print(ci.value_counts())

# 添加类别
ci_extended = ci.add_categories(['E'])
print("\n添加类别后的 CategoricalIndex:")
print(ci_extended)
print("新类别:", ci_extended.categories)

输出结果:

CategoricalIndex:
CategoricalIndex(['A', 'B', 'C', 'A', 'B', 'A'], categories=['A', 'B', 'C', 'D'], ordered=True, name='字母索引', dtype='category')

属性:
类别 (categories): Index(['A', 'B', 'C', 'D'], dtype='object')
有序性 (ordered): True
名称 (name): 字母索引
代码 (codes): [0 1 2 0 1 0]
唯一值 (unique): CategoricalIndex(['A', 'B', 'C'], categories=['A', 'B', 'C', 'D'], ordered=True, name='字母索引', dtype='category')
值计数 (value_counts):
A    3
B    2
C    1
dtype: int64

添加类别后的 CategoricalIndex:
CategoricalIndex(['A', 'B', 'C', 'A', 'B', 'A'], categories=['A', 'B', 'C', 'D', 'E'], ordered=True, name='字母索引', dtype='category')
新类别: Index(['A', 'B', 'C', 'D', 'E'], dtype='object')
示例 8: 处理缺失值
import pandas as pd
import numpy as np

# 创建包含缺失值的 CategoricalIndex
ci_with_na = pd.CategoricalIndex(['A', 'B', np.nan, 'A', 'C', np.nan],
                                 categories=['A', 'B', 'C'],
                                 name='含缺失值索引')

print("包含缺失值的 CategoricalIndex:")
print(ci_with_na)
print("缺失值检测:")
print(ci_with_na.isna())
print("缺失值数量:", ci_with_na.isna().sum())

# 删除缺失值
ci_no_na = ci_with_na.dropna()
print("\n删除缺失值后:")
print(ci_no_na)

输出结果:

包含缺失值的 CategoricalIndex:
CategoricalIndex(['A', 'B', nan, 'A', 'C', nan], categories=['A', 'B', 'C'], ordered=False, name='含缺失值索引', dtype='category')
缺失值检测:
[False False  True False False  True]
缺失值数量: 2

删除缺失值后:
CategoricalIndex(['A', 'B', 'A', 'C'], categories=['A', 'B', 'C'], ordered=False, name='含缺失值索引', dtype='category')
应用场景
  1. 内存优化:当处理大量重复的分类数据时,使用 CategoricalIndex 可以显著节省内存
  2. 有序分类数据:处理具有自然顺序的分类数据,如教育程度、评级等
  3. 数据一致性:确保数据只包含预定义的类别值
  4. 性能优化:在分组操作和某些计算中,CategoricalIndex 比普通索引更高效
  5. 语义明确:明确表示数据的分类性质,提高代码可读性
注意事项
  • CategoricalIndex 中的值必须是其类别的一部分,不能包含未定义的类别(除非特别允许)
  • 有序的 CategoricalIndex 支持比较操作,但无序的不支持
  • 在处理大型数据集时,CategoricalIndex 相比普通 Index 有显著的内存优势
  • 可以通过 add_categories()remove_categories() 等方法动态修改类别
  • CategoricalIndex 保留了原始数据的顺序,但内部使用整数代码来表示类别

通过 CategoricalIndex,我们可以高效地处理分类数据,在保证数据语义的同时优化内存使用和计算性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liuweidong0802

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值