为何pandas的value_counts()生成元组索引?如何转为普通索引?
Pandas value_counts返回MultiIndex的问题及解决
问题场景
给定如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame({'a': ["Q1", "Q2", "Q1", "P1"]})
对应的表格结构:
a 0 Q1 1 Q2 2 Q1 3 P1
执行counts = df.value_counts(normalize=True)统计后,结果的索引变成了MultiIndex类型:
MultiIndex([('Q1',), ('P1',), ('Q2',)], names=['a'])
希望索引是普通的字符串Index而非MultiIndex,因此提出两个问题:
- 为什么
value_counts会返回MultiIndex? - 是否有替代方案或解决方法?
问题解答
1. 为什么value_counts返回MultiIndex?
因为你调用的是DataFrame的value_counts方法,这个方法的设计初衷是支持对多列组合进行计数(比如同时统计列a和列b的组合出现次数)。为了保持API行为的一致性,不管你是传入单列还是多列,它都会统一返回MultiIndex作为索引,避免因为列数不同返回不同类型索引带来的代码适配问题。
2. 替代方案与解决方法
有三种简单的方式可以得到普通Index的统计结果:
- 方法一:直接调用Series的
value_counts
针对目标列(Series对象)调用value_counts,而不是对整个DataFrame调用:
counts = df['a'].value_counts(normalize=True)
此时counts.index就是普通的Index:
Index(['Q1', 'P1', 'Q2'], dtype='object', name='a')
- 方法二:转换已有的MultiIndex
如果已经得到了MultiIndex格式的结果,可以通过提取元组中的元素将其转换为普通Index:
# 方法1:提取指定层级的值 counts.index = counts.index.get_level_values(0) # 方法2:通过映射提取元组第一个元素 counts.index = counts.index.map(lambda x: x[0])
- 方法三:使用
groupby配合size计算占比
通过分组统计的方式也能实现相同的归一化计数效果,返回的索引是普通Index:
counts = df.groupby('a').size() / len(df)
内容的提问来源于stack exchange,提问作者Palinuro
相关产品推荐
相关产品推荐

