Pandas如何按唯一id分组统计各颜色字段的出现次数
Pandas 统计每个ID对应各颜色出现次数
问题场景
现有如下结构的DataFrame:
import pandas as pd df = pd.DataFrame({"id": [1, 2, 2, 1, 3, 3, 2, 1, 2], "colors": ['green', 'blue', 'green', 'yellow', 'yellow', 'yellow', 'green', 'red', 'black']})
该DataFrame包含id、colors两个长度相同的序列,id与colors之间无固定对应规则,例如id为1的记录可对应green、yellow、red等任意颜色值。
需求为生成新的DataFrame,规则如下:
- 第一列为所有唯一id值
- 后续每一列对应所有出现过的颜色值
- 单元格内容为对应id下该颜色的出现次数
预期输出结果:
| id | green | blue | yellow | red | black |
|---|---|---|---|---|---|
| 1 | 1 | 0 | 1 | 1 | 0 |
| 2 | 2 | 1 | 0 | 0 | 1 |
| 3 | 0 | 0 | 2 | 0 | 0 |
原有尝试代码的等值判断逻辑无法正常运行,原代码如下:
print(df.loc[df.id.unique() == df["id"], "colors"].value_counts())
实现方案
方案1:使用pd.crosstab(最简洁)
pandas内置的交叉表函数专门用于这类分组频次统计场景,自动补全缺失组合为0,一行代码即可得到结果:
# 直接生成结果,id为行索引 result = pd.crosstab(index=df['id'], columns=df['colors']) # 如果需要把id转为普通列,追加reset_index即可 result = pd.crosstab(index=df['id'], columns=df['colors']).reset_index()
方案2:groupby + unstack
如果更熟悉分组聚合逻辑,可以用分组计数后转列的方式实现,效果完全一致:
result = df.groupby(['id', 'colors']) # 按id、颜色双字段分组 .size() # 统计每组的记录条数 .unstack(fill_value=0) # 将颜色从行索引转为列,缺失值填充为0 .reset_index() # 将id从索引转为普通列
两种方案运行后输出的结果都和预期完全匹配。
内容的提问来源于stack exchange,提问作者Dryade
相关产品推荐
相关产品推荐

