DataFrame多列分组求和结果异常问题排查
分组求和结果不符的原因排查
场景与需求
将多个DataFrame拼接生成testoutput2后,按Level 4、Region IEA Level 1两列分组,计算各年份列(如2018 IEA)的求和结果,最终生成以「年份+IEA」为键的DataFrame字典。
数据示例
testoutput2的结构与数据如下:
+-----+-------+---------+-----------+--------------------+----------+----------+----------+----------+ | Key | Index | Level 4 | IEA WEM22 | Region IEA Level 1 | 2018 IEA | 2019 IEA | 2020 IEA | 2021 IEA | +-----+-------+---------+-----------+--------------------+----------+----------+----------+----------+ | FRA | - | 12,000 | 12,000 | Advanced economies | 54 | 37 | 26 | 0.00 | | FRA | 1 | 11,000 | 11,000 | Advanced economies | 8 | 8 | 7 | 11 | | FRA | 3 | 31,100 | 31,100 | Advanced economies | 4 | 3 | 3 | 0.00 | | BEL | - | 12,000 | 12,000 | Advanced economies | 8 | 9 | 7 | 0.00 | | BEL | 1 | 11,000 | 11,000 | Advanced economies | 1 | 1 | 1 | 2 | | BEL | 3 | 31,100 | 31,100 | Advanced economies | 1 | 1 | 1 | 0.00 | +-----+-------+---------+-----------+--------------------+----------+----------+----------+----------+
期望输出
以2018 IEA为例,正确的分组求和结果应为:
+---------+--------------------+-----+ | Level 4 | Region IEA Level 1 | Sum | +---------+--------------------+-----+ | 12,000 | Advanced economies | 62 | | 11,000 | Advanced economies | 9 | | 31,100 | Advanced economies | 5 | +---------+--------------------+-----+
问题现象
运行以下代码后,求和结果与预期不符(如2018 IEA的结果为61、8、4):
scen_name = "IEA" scen_reg_out_dict={} year_list_2 = [2018,2019,2020,2021] for year_var in year_list_2: scen_reg_out_dict[str(year_var) + " " + scen_name] = testoutput2.groupby(['Level 4','Region IEA Level 1'])[str(year_var) + " " + scen_name].agg(['sum']).astype('int64')
原因分析
核心问题是浮点精度丢失导致的强制转换截断:
- 从数据中能看到部分年份列存在浮点值(如
2021 IEA列的0.00),说明这些列的数据类型是float而非int。 - 浮点型数据在计算过程中可能出现精度误差(比如理论值62实际存储为
61.99999999999999),此时直接用astype('int64')强制转换会直接截断小数部分,得到错误的整数结果。
修正方案
先对求和结果做四舍五入处理,再转换为整数:
scen_name = "IEA" scen_reg_out_dict={} year_list_2 = [2018,2019,2020,2021] for year_var in year_list_2: col_name = str(year_var) + " " + scen_name # 先求和,四舍五入后转整数类型 agg_result = testoutput2.groupby(['Level 4','Region IEA Level 1'])[col_name].agg(['sum']).round().astype('int64') scen_reg_out_dict[col_name] = agg_result
内容的提问来源于stack exchange,提问作者DGMS89
相关产品推荐
相关产品推荐

