如何在Pandas中统计各列唯一值的列内出现次数并按元素汇总?
问题描述
假设我有如下DataFrame:
| Index | one | two | three |
|---|---|---|---|
| First | A | B | C |
| Second | C | A | B |
| Third | B | A | C |
我期望得到 df.iloc[:,1:] 各列中唯一值的计数结果,如下表格所示:
| Item | one | two | three |
|---|---|---|---|
| A | 1 | 2 | 0 |
| B | 1 | 1 | 1 |
| C | 1 | 0 | 2 |
计数说明:
| Item | one | two | three |
|---|---|---|---|
| A | 1(第1列仅1个A) | 2(第2列有2个A) | 0(第3列无A) |
| B | 1(第1列仅1个B) | 1(第2列仅1个B) | 1(第3列有1个B) |
| C | 1(第1列仅1个C) | 0(第2列无C) | 2(第3列有2个C) |
我尝试过以下两种方法,但效果不理想:
df3.iloc[:,1:].value_counts().to_frame('counts').reset_index()df[df.columns[1:]].value_counts()
逐个遍历列执行 .value_counts() 再整理的方法太繁琐,因为各列结果顺序不一致,请问该如何正确实现需求?
解决方案
可以用 pd.DataFrame.apply 结合 value_counts,统一索引并填充缺失值为0,最后调整索引名称即可:
import pandas as pd # 构造示例DataFrame df = pd.DataFrame( {'one': ['A', 'C', 'B'], 'two': ['B', 'A', 'A'], 'three': ['C', 'B', 'C']}, index=['First', 'Second', 'Third'] ) # 提取目标列并计算各列值计数 result = df.iloc[:, 1:].apply(pd.Series.value_counts).fillna(0).astype(int) # 设置索引名称 result.index.name = 'Item' print(result)
执行后输出结果完全符合需求:
two three Item A 2 0 B 1 1 C 0 2
代码解释
df.iloc[:,1:]:提取从第2列开始的所有目标列.apply(pd.Series.value_counts):对每一列执行值计数,自动按各列的唯一值生成索引.fillna(0):将不存在的值对应的计数填充为0.astype(int):把浮点型的计数转为整数类型result.index.name = 'Item':给索引设置名称,匹配期望的表格格式
如果需要把Item作为普通列而非索引,只需执行result.reset_index()即可。
内容的提问来源于stack exchange,提问作者Sudoh
相关产品推荐
相关产品推荐

