如何在Pandas中向量化优化我的低效代码?
如何在Pandas中向量化优化我的低效代码?
看起来你现在的代码在大数据量下肯定会跑得很慢——你踩了Pandas里两个典型的效率坑:逐行遍历索引和反复调用.loc做行级查找。.loc本身不算特别慢,但架不住你循环里每次都调用,而且Python层面的逐行循环本来就和Pandas的向量化设计相悖。我给你分两种情况说说优化方案:
情况一:没法修改myClass的代码
如果不能改动类的实现,那我们先把手动循环换成Pandas的apply方法,它内部做了C级别的优化,比你自己写Python循环快很多,同时也能避免反复用.loc:
# 先定义处理单行的函数 def process_single_row(row): # 初始化类实例,直接用row['name']比.loc快 obj = myClass(row['name']) # 遍历所有列调用方法 for col in [f'col{x}' for x in range(1, 18)]: obj.class_method({col: row[col]}) return obj # 用apply逐行处理,最后转成字典(键就是原索引) my_dict = df.apply(process_single_row, axis=1).to_dict()
为什么这个更好?
apply会把整行打包成Series传递,访问row[col]的开销比df.loc[i, col]小很多- 避免了手动遍历索引的Python循环,把循环逻辑交给Pandas内部优化的代码处理
情况二:可以修改myClass的代码(最优解)
如果能改类的实现,那我们可以直接做真正的向量化优化——让类支持批量处理整列的数据,彻底抛弃行循环:
比如修改类,增加批量处理的方法:
class myClass: def __init__(self, names): # 接收整个name列的数组,而不是单个name值 self.names = names # 这里保留你原来的初始化逻辑,适配数组输入 def batch_class_method(self, col_name, col_values): # 批量处理整列的数据,而不是单个值 # 比如原来的class_method是处理单个键值对,现在改成处理整个数组 # 这里写你的批量处理逻辑 pass # 使用方式:一次性传入整列数据 my_obj = myClass(df['name'].values) for col in [f'col{x}' for x in range(1, 18)]: my_obj.batch_class_method(col, df[col].values)
这种方式的效率会提升几个数量级,因为Pandas的列本质是NumPy数组,批量处理数组是C级别的运算,完全避开了Python循环的开销。
额外小提示
如果你的DataFrame特别大,还可以试试swifter库(需要安装),它会自动判断用普通apply还是转成Dask做并行处理,不用改太多代码就能进一步提速。
备注:内容来源于stack exchange,提问作者regina_adams
相关产品推荐
相关产品推荐

