问题现状:数据量60w条的dataframe,需要进行一些条件判断和计算,一般为满足某条件的则进行加减乘除计算,不满足的则为0,比如:
result_frame['aaa'] = np.vectorize(lambda x, y: 0 if y == 0 else x / y)(
base_frame['bbb'], base_frame['ccc'])
但是不知道为什么,使用这种方法进行计算时,有一些数据明明手动计算出来是有数值 ,但是上述代码计算出来是0,这块研究了下大概是向量偏移的问题,后来也没有深究就直接换方法处理了。
解决历程:
1.使用apply方法,好处是算出来的结果和手动计算是一致的,但是apply方法相当于是逐行进行计算的,导致计算时间大打折扣,计算完大概需要15分钟
ps: 最后的axis不要忘记写了,否则会报错
result_frame['aaa'] = base_frame.apply(lambda row: 0 if row['ccc'] == 0 else row['bbb'] / row['ccc'], axis=1)
2.为了解决代码执行效率问题,apply方法注定要被抛弃,后来有发现有一个方法可以实现if相同的效果:where语句,上述代码可以修改成:
result_frame['aaa'] = (base_frame['bbb'].div(base_frame['ccc'])).where(base_frame['ccc'] != 0, 0)
但是使用where是有条件的:
一:前后frame的索引index必须是一样的。上述代码中前面的result_frame和base_frame是不同的dataframe,但是这俩的行数,索引都是一样的,即每一行的数据都是对应的上的,直观一点就是,这里面的result_frame是base_frame的一部分:
result_frame = base_frame[['bbb', 'ccc', 'ddd']]
二:where支持多个条件,可以使用&(且)、|(或)等进行连接
拓展说明:
where判断是否为null值:
result_frame['aaa'] = base_frame['bbb'].where(base_frame['ccc'].isnull(), 1)
where判断是否为NA:
result_frame['aaa'] = base_frame['bbb'].where(base_frame['ccc'].notna(), 1)
dataframe常用的方法:
sum() 加: base_frame[['aaa', 'bbb']].sum(axis=1)
sub() 减: base_frame['aaa'].sub(base_frame['bbb'])
mul() 乘: base_frame['aaa'].mul(base_frame['bbb'])
div() 除:base_frame['aaa'].div(base_frame['bbb'])
最终,效率大幅提升,由最开始的15分钟,降至 3 分钟!