Python Pandas多列分组求和内存溢出及cumsum结果不符问题咨询
问题1解答
错误原因
pandas对多列category类型执行分组操作时,默认参数observed=False,会基于所有category列的取值水平计算笛卡尔积作为全部分组基数,而非仅计算数据中实际存在的组合。你有13个category列,哪怕每列仅有几十个取值,乘积也会达到百亿甚至千亿级别,底层预分配内存时会按照这个极端夸张的维度申请空间,最终触发内存溢出,和你的实际数据量无关。
规避方案
创建分组对象时添加observed=True参数,仅保留数据中实际存在的分组组合即可:
gp = df_test.groupby(by=gp_cols, as_index=True, observed=True) # 之后直接调用sum即可正常得到结果,不会触发内存错误 res = gp['quantity'].sum().reset_index()
问题2解答
结果异常原因
- 你使用的
gp是未加observed=True参数创建的异常分组对象,底层分组逻辑已经混乱,cumsum的计算结果本身就不正确,甚至存在随机不稳定的情况,导致每次运行求和结果都不一致。 - 你先对
df_test执行了sort_values重排索引,但gp是基于排序前的原始DataFrame创建的,cumsum返回结果的索引和排序后的df_test索引不匹配,join环节出现对齐错误,进一步导致结果异常。
无拼接列的正确实现方案
不需要通过cumsum+drop_duplicates绕路,直接使用修正后的分组对象即可得到正确结果:
gp_cols = ['dddd-mm', 'province', 'city', 'maker', 'brand', 'model', 'model-year', 'color', 'liters', 'fueltype','type', 'appType', 'domesticimported'] # 加observed=True解决多category列分组内存问题 gp = df_test.groupby(by=gp_cols, as_index=False, observed=True) res = gp['quantity'].sum() # 校验总和,和原数据完全一致 print(res['quantity'].sum(), df_test['quantity'].sum())
内容的提问来源于stack exchange,提问作者kk120120
相关产品推荐
相关产品推荐

