如何用Pandas高效按col1统计col2、col3各唯一值的频数?
问题描述
现有如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame(columns=['col1', 'col2', 'col3']) df.col1 = ['q1', 'q2', 'q2', 'q3', 'q4', 'q4'] df.col2 = ['b', 'a', 'a', 'c', 'b', 'b'] df.col3 = ['p', 'q', 'r', 'p', 'q', 'q']
对应的表格:
| col1 | col2 | col3 | |
|---|---|---|---|
| 0 | q1 | b | p |
| 1 | q2 | a | q |
| 2 | q2 | a | r |
| 3 | q3 | c | p |
| 4 | q4 | b | q |
| 5 | q4 | b | q |
需要按col1分组,统计col2和col3中各唯一值的出现次数,把这些唯一值作为列,col1的唯一值作为行,最终得到如下格式的结果:
col1 a b c p q r q1 0 1 0 1 0 0 q2 2 0 0 0 1 1 q3 0 0 1 1 0 0 q4 0 2 0 0 2 0
目前用循环实现但效率太低,想找高效的Pandas/pythonic写法。
高效实现方案
直接用Pandas的内置函数组合操作,完全避开循环,代码简洁还高效:
# 1. 把col2、col3转成长格式,保留col1作为分组依据 melted = df.melt(id_vars='col1', value_vars=['col2', 'col3'], value_name='value') # 2. 分组统计次数,再转成宽格式,缺失的组合填0 result = melted.groupby(['col1', 'value']).size().unstack(fill_value=0) # 3. 可选:按需求排序列的顺序(和示例对齐) result = result.reindex(columns=['a', 'b', 'c', 'p', 'q', 'r']) # 可选:把col1从索引转回普通列 result = result.reset_index()
运行后得到的结果和期望完全一致:
| col1 | a | b | c | p | q | r | |
|---|---|---|---|---|---|---|---|
| 0 | q1 | 0 | 1 | 0 | 1 | 0 | 0 |
| 1 | q2 | 2 | 0 | 0 | 0 | 1 | 1 |
| 2 | q3 | 0 | 0 | 1 | 1 | 0 | 0 |
| 3 | q4 | 0 | 2 | 0 | 0 | 2 | 0 |
操作说明:
melt:把原本分散在col2、col3的值合并到同一列,这样就能统一统计所有值的出现次数,不用分别处理两列。groupby+size:按col1和合并后的value分组,统计每组的行数,也就是对应值的出现次数。unstack:把value里的唯一值转成列名,同时用fill_value=0补全那些没出现过的组合,避免出现NaN。reindex:如果需要固定列的顺序,就用这个方法指定排列顺序,确保和示例完全匹配。
内容的提问来源于stack exchange,提问作者Kallol
相关产品推荐
相关产品推荐

