使用Pandas按另一列指定的不同小数位数对数值列四舍五入
两段代码表现差异的原因
- Pandas对算术运算符(如乘、加、减等)做了面向Series的重载,两个同长度的Series执行算术运算时,会默认逐元素配对计算,因此直接写
df['numbers']*df['decimal']可以正常运行。 - Python内置的
round()是普通标量函数,没有做Pandas向量化适配,它的第二个参数要求接收单个整数,传入完整的Series对象时,函数无法将整个Series转换为单个int值,因此抛出TypeError: cannot convert the series to <class 'int'>报错。
实现需求的方案
方案1:逐行apply处理(写法简单,适合小数据量)
import pandas as pd df = pd.DataFrame( data = { 'numbers' : [1.2345, 2.3456, 3.4567], 'decimal' : [2,3,2] } ) # axis=1指定按行遍历 df['newcolA'] = df.apply(lambda row: round(row['numbers'], row['decimal']), axis=1) print(df)
运行输出和预期结果完全一致。
方案2:向量化运算(性能更高,适合十万行以上的大数据量)
利用数学计算逻辑绕开Python层循环,先把数值放大对应小数位的10的n次方,取整后再缩回去,全程是Pandas原生向量化操作,运行速度远高于apply方案:
df['newcolA'] = df['numbers'].mul(10 ** df['decimal']).round().div(10 ** df['decimal'])
内容的提问来源于stack exchange,提问作者Dan Boucher
相关产品推荐
相关产品推荐

