如何不使用iterrows()完成函数向量化,提升Pandas大数据集处理效率
优化建议
1 低改造成本快速提速:替换iterrows为itertuples
iterrows遍历速度慢的核心原因是每一行都会生成一个Series对象,额外开销极大,换成itertuples返回命名元组,不需要调整业务逻辑就能获得10~100倍的遍历速度提升,示例改造:
for number in [95,2,3,4]: line, vehicles = getLineAndVehicle(number) vehicles = vehicles[vehicles['DistanceFromPoint'] == 0].reset_index(drop=True) total_delays = [] # 换成itertuples遍历,name=None返回普通元组速度更快,需要属性访问可以保留name='Vehicle' for vehicle_row in vehicles.itertuples(name=None): # 元组下标对应vehicles的列顺序,第0位为行索引,后续依次对应各列,也可用命名元组直接访问属性 delays = matchTimeWithStops(line, vehicle_row) if not delays.empty: final_delay = calculateTheDelay(delays, vehicle_row) total_delays.append(final_delay) else: total_delays.append(None) vehicles['delay'] = total_delays
2 彻底消除循环:函数批量化改造
你提到可以调整matchTimeWithStops仅返回三个需要的取值,可以直接将该函数改造成接收全量vehicles DataFrame和line参数,一次性输出所有行对应三个值的结果集,再把calculateTheDelay改成基于列的向量运算,完全去掉内层遍历,性能会有质的提升。
3 数据加载阶段优化
源CSV有900MB,加载时就做前置优化:
- 读CSV时指定
dtype参数,给每个列设置最小可用类型,比如整数列用int32、时间列直接用parse_dates转成datetime类型,避免后续转换开销,同时内存占用可降低40%以上 - 若所有线路数据存在同一份CSV中,读入时就过滤
DistanceFromPoint == 0的行,不需要的行直接不加载到内存,减少后续运算量
4 外层循环并行化
当前外层遍历的4个线路计算完全独立,没有依赖关系,可以用多进程并行计算4个线路的结果,CPU核心足够的情况下最多可以再缩短75%的耗时。
内容的提问来源于stack exchange,提问作者Filip
相关产品推荐
相关产品推荐

