Python pandas如何截断指定列小数位用于计算且不修改原列
报错根因
math.trunc 是Python原生的标量计算函数,仅支持单个数值入参,无法直接对pandas Series整列对象做运算,这就是触发TypeError: type Series doesn't define __trunc__ method的直接原因。
高效实现方案
使用numpy提供的向量化截断函数np.trunc替代math.trunc即可,该函数原生支持pandas Series、numpy数组的批量运算,性能远高于逐行循环/apply写法,同时满足所有约束:
- 截断操作仅在逻辑判断时生成临时中间值,计算完成后自动销毁,不会修改原始列数据,也不会生成额外永久列
- 截断逻辑为直接舍去低位小数,不做四舍五入,完全匹配给出的样例判定规则
- 自动兼容NaN值:NaN参与比较时会返回False,无需额外处理前序行的空值
- 向量化运算性能优异,适配多列大数据量场景
修正后的完整代码如下:
import numpy as np def scenario1(df): # 封装临时截断逻辑,调整截断位数直接修改乘数即可 def truncate_calc(s, decimals=3): multiplier = 10 ** decimals return np.trunc(s * multiplier) / multiplier df['scenario1'] = np.where( (df.close <= 2) & (df.tenkan > df.tenkan.shift(1)) & (df.kijun > df.kijun.shift(1)) & (truncate_calc(df.tenkan) == truncate_calc(df.kijun)) & (df.span_a > df.span_a.shift(1)) & (df.span_b > df.span_b.shift(1)) & (truncate_calc(df.span_a) == truncate_calc(df.span_b)) & (df.volume <= 300000), 1, 0 ) return df
补充说明
- 如果需要调整截断小数位数,只需要给
truncate_calc传不同的decimals参数即可:比如截断到1位小数传decimals=1,就可以实现样例中0.9954、0.995642截断后均为0.9的判定效果。 - 所有截断计算都是内存中的临时操作,不会留存到最终返回的DataFrame中,返回结果仅新增需要的
scenario1二进制列,原始数值列完全保持原样,不会产生额外冗余列。 - 前序行因为
shift(1)产生的NaN、原始数据自带的NaN,在逻辑与运算中都会被判定为False,不会被误标记为1,无需额外做空值填充处理。 - 注意:不要使用
Series.apply+math.trunc的逐行写法,这类写法是Python层循环实现,性能比np.trunc的C层向量化实现低1~2个数量级,数据量较大时会有明显卡顿。
内容的提问来源于stack exchange,提问作者Garrad2810
相关产品推荐
相关产品推荐

