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

使用Pandas为54个大CSV文件新增列的实现方案问询

问题:海量CSV数据新增列的实现是否适用及优化方案?

我拥有54个CSV文件,每个文件包含300万行数据。需为每个CSV文件新增列,当前实现代码如下:

local_list = pd.DataFrame(columns=["ORI_LOCAL_NAME","DES_LOCAL_NAME"])
for i in range(0,df.__len__()):
    row = df.iloc[i,:]
    ori_name = row['ORI_TOLL_NAME']
    des_name = row['DES_TOLL_NAME']
    ori_local_name = toll_info[ori_name]
    des_local_name = toll_info[des_name]
    local_list = local_list.append({"ORI_LOCAL_NAME": ori_local_name, "DES_LOCAL_NAME": des_local_name}, ignore_index=True)

请问该实现是否适用于海量数据场景,有无优化方案?


回答:

兄弟,你这个实现完全不适合海量数据场景,甚至可以说是Pandas处理大数据的典型反面案例——我给你拆解问题和优化方案:

为什么当前代码不行?

  • 逐行循环处理300万行:Pandas的设计核心是向量化操作,逐行遍历iloc的速度慢到离谱,300万行可能要跑几十分钟甚至更久。
  • 循环里用append():每次append都会创建一个新的DataFrame对象,旧对象还要等待GC回收,内存占用会随着循环次数爆炸式增长,处理到几十万行时大概率会触发内存溢出。

优化方案(按优先级排序)

1. 用向量化映射替代逐行循环

toll_info看起来是个字典(或者可以转成字典),直接用map()方法批量处理整个列,速度能提升几个数量级:

# 直接在原DataFrame上生成新列,完全不需要创建额外的local_list
df['ORI_LOCAL_NAME'] = df['ORI_TOLL_NAME'].map(toll_info)
df['DES_LOCAL_NAME'] = df['DES_TOLL_NAME'].map(toll_info)

这两行代码就能搞定300万行数据,本质是让Pandas在底层用C语言批量处理,比Python循环快几十倍。

2. 分块读取处理单个CSV文件

每个CSV有300万行,54个文件总数据量超过16亿行,一次性加载到内存基本不可能,必须分块处理:

import pandas as pd

def process_single_csv(file_path, toll_info):
    processed_chunks = []
    # chunksize根据你的内存情况调整,比如10万行一块,内存压力小就调大
    for chunk in pd.read_csv(file_path, chunksize=100000):
        # 对每个块做向量化映射
        chunk['ORI_LOCAL_NAME'] = chunk['ORI_TOLL_NAME'].map(toll_info)
        chunk['DES_LOCAL_NAME'] = chunk['DES_TOLL_NAME'].map(toll_info)
        processed_chunks.append(chunk)
    # 合并所有块并返回
    return pd.concat(processed_chunks, ignore_index=True)

# 遍历所有CSV文件处理
for csv_path in your_csv_file_list:  # 替换成你的54个文件路径列表
    result_df = process_single_csv(csv_path, toll_info)
    # 保存处理后的文件,建议存新文件避免覆盖原数据
    result_df.to_csv(f"processed_{csv_path}", index=False)

分块处理能把内存占用控制在单个块的大小,避免内存溢出,而且每个块的处理依然是向量化的,速度不会慢。

3. 额外的内存/速度优化点

  • 如果toll_info是从其他表格来的,转成pd.Series再map,速度会比字典更快:
    toll_series = pd.Series(toll_info)
    df['ORI_LOCAL_NAME'] = df['ORI_TOLL_NAME'].map(toll_series)
    
  • 读取CSV时指定dtype参数,减少内存占用:比如已知ORI_TOLL_NAME是字符串,可以指定dtype={'ORI_TOLL_NAME': 'string'},避免Pandas自动推断成object类型浪费内存。
  • 用usecols参数只读取需要的列:如果原CSV里有很多不需要的列,读取时只加载ORI_TOLL_NAME、DES_TOLL_NAME以及其他需要保留的列,进一步降低内存压力。

内容的提问来源于stack exchange,提问作者Jungseok Cho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:08:13