pandas.crosstab调用mean()处理Decimal对象失效如何解决
问题根因
pandas.crosstab 传入aggfunc='mean'时,默认调用NumPy实现的均值计算逻辑,NumPy无法识别decimal.Decimal类型,聚合时会返回空值,最终得到空的交叉表结果。
无类型转换解决方案
不需要将Decimal转换为float或其他类型,只需自定义适配Decimal的均值计算函数,传入aggfunc参数即可。自定义函数直接用Python原生+Decimal的运算逻辑计算,全程不做类型转换,可完整保留Decimal精度。
修正后可运行代码
#!/usr/bin/env python3 import decimal import pandas def decimal_mean(seq): val_list = seq.tolist() return sum(val_list) / decimal.Decimal(len(val_list)) df = pandas.DataFrame({ 'foo': list('AABB'), 'bar': list('XYXY'), 'val': [1.4, 6.2, 7, 87.12]}) # 生成Decimal类型的数值列 df.val = df.val.apply(lambda x: round(decimal.Decimal(x), 4)) print(df) tab = pandas.crosstab( index=df.foo, columns=df.bar, values=df.val, aggfunc=decimal_mean ) print(tab)
运行结果
foo bar val 0 A X 1.4000 1 A Y 6.2000 2 B X 7.0000 3 B Y 87.1200 bar X Y foo A 1.4000 6.2000 B 7.0000 87.1200
注意事项
- 不要直接传入
pandas.Series.mean作为聚合函数,该方法底层依赖NumPy计算逻辑,同样无法正确处理Decimal类型 - 自定义聚合函数中不要引入float类型转换,所有运算使用Decimal内置方法即可保证精度不丢失
内容的提问来源于stack exchange,提问作者buhtz
相关产品推荐
相关产品推荐

