如何用Python Pandas按ID分组统计Prob列0和1的出现次数并生成新列
按ID分组统计Prob列0和1的出现次数
原始数据
import pandas as pd d = {'ID':['X1','Y1','Z3','X1','X1','Z3','L1','H5','H5','H5'],'Prob':[0,0,1,1,1,1,0,0,0,0]} frame = pd.DataFrame(d)
需求目标
按ID分组,统计Prob列中0和1的出现次数,生成zero_count和one_count两列,预期结果:
ID zero_count one_count X1 1 2 Y1 1 0 Z3 0 2 L1 1 0 H5 3 0
错误尝试分析
用户尝试的代码无法得到预期结果:
frame.groupby(['ID','prob'])['index'].count().reset_index(name='zero_count')
问题点:
- 列名拼写错误:
prob应为大写的Prob - 分组逻辑仅生成单一计数列,无法拆分出0和1的独立统计列
- 引用了不存在的
index列,统计行数应直接用size()或针对目标列计数
解决思路与正确代码
方法一:使用crosstab(最简洁)
利用pd.crosstab直接生成交叉统计表格,自动计算每个ID下0和1的出现次数,再重命名列即可:
result = pd.crosstab(frame['ID'], frame['Prob']).rename(columns={0: 'zero_count', 1: 'one_count'}).reset_index()
方法二:分组后用value_counts+unstack
先按ID分组,对Prob列做值计数,再通过unstack将行维度的统计结果转为列,最后填充缺失值为0并重置索引:
result = frame.groupby('ID')['Prob'].value_counts().unstack(fill_value=0).rename(columns={0: 'zero_count', 1: 'one_count'}).reset_index()
方法三:自定义聚合函数
通过自定义函数实现每个分组内0和1的数量统计,适合扩展更复杂的统计逻辑:
def count_zero_one(group): return pd.Series({ 'zero_count': (group['Prob'] == 0).sum(), 'one_count': (group['Prob'] == 1).sum() }) result = frame.groupby('ID').apply(count_zero_one).reset_index()
三种方法均可得到符合预期的结果,其中crosstab代码最简洁,适配这类基础交叉统计需求。
内容的提问来源于stack exchange,提问作者Chip
相关产品推荐
相关产品推荐

