Pandas中直接sum与groupby后sum结果不同的原因排查
问题原因及解决办法
分组聚合sum结果低于直接sum,大概率是以下原因导致:
分组键包含缺失值,对应行被自动排除
Pandas的groupby默认会剔除分组键(col2/col3)中任意一列存在NaN的行——哪怕这些行的col1有有效值,也不会被纳入分组计算。而直接调用df['col1'].sum()会计算所有col1非NaN的行,包括分组键为NaN的行,因此分组sum结果会更低。
验证方法:计算分组键含NaN的行的col1总和,看是否等于直接sum与分组sum的差值:# 计算分组键存在缺失的行的col1总和 missing_group_keys_sum = data[data[['col2','col3']].isna().any(axis=1)]['col1'].sum() # 对比差值是否匹配 print(df['col1'].sum() - data_grouped.sum() == missing_group_keys_sum)解决办法:给
groupby添加dropna=False参数(注意是传给groupby,不是sum方法):data_grouped = data[['col2','col3','col1']].groupby(['col2','col3'], dropna=False)['col1'].sum()col1存在隐性无效值(如字符串类型的数值)
如果col1是字符串类型,部分无法转为数值的无效值会被直接sum忽略,分组sum同样会忽略这类值。但如果分组时某些组的无效值占比更高,可能导致整体分组sum更低。可以验证col1的数据类型和无效值:# 检查col1的数据类型 print(data['col1'].dtype) # 筛选无法转为数值的行 invalid_rows = data[pd.to_numeric(data['col1'], errors='coerce').isna()] print(len(invalid_rows)) # 查看无效行数量解决办法:先将col1转为数值类型:
data['col1'] = pd.to_numeric(data['col1'], errors='coerce')分组前的子集操作意外过滤了行
虽然data[['col2','col3','col1']]是选择列,但如果原data的列名存在拼写错误,可能生成全NaN的列,极端情况下可能触发行过滤(概率极低)。可以验证子集行数是否和原data一致:print(len(data) == len(data[['col2','col3','col1']]))
内容的提问来源于stack exchange,提问作者Lukas Tomek
相关产品推荐
相关产品推荐

