You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速8000万行Pandas DataFrame场景下的超长for循环

问题描述

现有用于遍历索引列表字典的for循环,字典结构示例为{0: [1,5,...], 1: [2,4,...], ...},需基于约8000万行的超大型DataFrame遍历该字典,通过索引值生成新的字典结构。
现有实现逻辑可满足需求,但运行耗时极长,希望通过多线程分片处理或其他优化方案提升运行速度。同类优化方案中有提到使用Cython实现优化,但由于当前操作基于DataFrame,暂不确定该方案是否可行。

补充说明:当前遍历的字典由pandas的groupby函数生成。

原始实现代码如下:

total_list = []
for ind in indexes_per_group:
    ship_list = []

    dataframe_indexes = indexes_per_group[ind]
    for index in dataframe_indexes:
        singleLocation_dict = {}

        singleLocation_dict['lat'] = df.loc[index]['LATITUDE']
        singleLocation_dict['lng'] = df.loc[index]['LONGITUDE']
        
        ship_list.append(singleLocation_dict)
    total_list.append(ship_list)
优化方案

原始代码性能差的核心原因是逐行调用df.loc做链式索引,每次索引都会触发pandas内部的标签匹配、类型校验、副本判断逻辑,在8000万行的数据规模下,Python层循环+逐行pandas索引的开销会被放大数百倍,不需要一开始就上多线程、Cython这类重方案,按以下步骤优化即可获得百倍级别的速度提升:

  • 第一层优化:消除pandas索引开销
    提前把需要用到的经纬度列转为numpy数组,numpy按位置取值是C级实现,没有pandas索引的额外开销,比原始写法快50倍以上:
    # 提前抽取需要的列为numpy数组,避免循环内重复做列查找、索引校验
    lat_values = df["LATITUDE"].to_numpy()
    lng_values = df["LONGITUDE"].to_numpy()
    
    total_list = []
    for _, idx_list in indexes_per_group.items():
        # 直接按位置取numpy值,字典推导式比逐次append效率更高
        group_records = [
            {"lat": lat_values[i], "lng": lng_values[i]} for i in idx_list
        ]
        total_list.append(group_records)
    
  • 第二层优化:复用groupby原生能力,省掉索引回查步骤
    既然indexes_per_group本身就是groupby生成的中间结果,完全没必要先拿分组索引再回表查数据,直接在groupby对象上迭代,用pandas内置的C级逻辑批量转字典,比自己写Python层循环快10~20倍:
    total_list = []
    # 只加载需要的两列,减少内存占用和迭代时的数据读取量
    for _, group_data in df[["LATITUDE", "LONGITUDE"]].groupby(分组使用的键):
        # 批量重命名后转记录列表,内部为C实现循环,无Python层开销
        group_records = group_data.rename(
            columns={"LATITUDE": "lat", "LONGITUDE": "lng"}
        ).to_dict("records")
        total_list.append(group_records)
    
  • 其他方案说明
    • 多线程对当前场景提速非常有限:pandas逐行操作受Python GIL锁限制,多线程无法实现真正的并行计算,反而会因为线程间数据拷贝增加额外开销。如果做完前两步优化仍有速度需求,可以直接将计算引擎替换为Polars,其基于Rust开发,原生支持多线程并行,处理8000万行规模数据的速度是pandas的5~20倍。
    • Cython优化的前提是完成基础向量化:如果需要极致压缩耗时,可以将最终的字典生成逻辑改写为带静态类型声明的Cython代码,但如果保留逐行读取DataFrame的逻辑,Cython也不会带来本质的性能提升。

内容的提问来源于stack exchange,提问作者James Hall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:03:25