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

如何用Pandas仅加载指定列处理大CSV并输出全列?

优化Pandas读取超大CSV的方案:仅读取必需列

完全可以通过仅读取任务必需的列来大幅降低read_csv的耗时,这是处理超大CSV文件时最有效的优化手段之一。结合你的任务流程,我们可以分两种场景实现优化:

场景1:最终输出需要保留原CSV的所有列

如果你的结果需要完整保留原CSV的所有字段,直接只读部分列无法满足拼接需求,但可以分两个阶段处理,先快速完成筛选逻辑,再精准读取需要保留的行:

阶段1:轻量读取必要列,确定需保留的索引

仅读取索引列(primary_idx_list)和目标处理列(that_col),完成匹配、标记删除行的逻辑,记录需要保留的行索引:

# 定义必需列:索引列 + 目标处理列
required_cols = primary_idx_list + [that_col]

# 仅读取必需列,大幅减少IO和内存开销
csv2_df_light = pd.read_csv(
    csv2, 
    sep='\x1D', 
    engine='python', 
    skiprows=1, 
    skipfooter=1, 
    header=0, 
    dtype=str, 
    keep_default_na=False,
    usecols=required_cols  # 指定仅读取这些列
)
csv1_df_light = pd.read_csv(
    csv1, 
    sep='\x1D', 
    engine='python', 
    skiprows=1, 
    skipfooter=1, 
    header=0, 
    dtype=str, 
    keep_default_na=False,
    usecols=required_cols
)

# 设置索引,用于行匹配
csv2_df_light.set_index(primary_idx_list, inplace=True, verify_integrity=verify_integrity)
csv1_df_light.set_index(primary_idx_list, inplace=True, verify_integrity=verify_integrity)

# 执行字段处理逻辑
def resolver(v1, v2):
    return '$Delete' if v1 == 'A' and v2 == 'B' else (v1 if v1 == 'A' and v2 == 'C' else (v2 if pd.notna(v2) else v1))

csv2_df_light[that_col] = csv1_df_light[that_col].combine(csv2_df_light[that_col], resolver)

# 筛选需要保留的索引:csv1中未在csv2出现的行 + csv2中未标记删除的行
keep_csv1_idx = csv1_df_light.index[~csv1_df_light.index.isin(csv2_df_light.index)]
keep_csv2_idx = csv2_df_light.index[csv2_df_light[that_col] != '$Delete']

阶段2:分块读取完整数据并筛选目标行

通过分块读取原CSV,只保留阶段1确定的索引行,避免一次性加载超大文件到内存:

# 定义分块读取并筛选的工具函数
def read_filtered_csv(file_path, keep_idx, idx_cols):
    chunks = []
    # 分块读取,chunksize可根据内存调整
    for chunk in pd.read_csv(
        file_path, 
        sep='\x1D', 
        engine='python', 
        skiprows=1, 
        skipfooter=1, 
        header=0, 
        dtype=str, 
        keep_default_na=False,
        chunksize=10000
    ):
        chunk.set_index(idx_cols, inplace=True)
        # 筛选当前块中需要保留的行
        filtered_chunk = chunk.loc[chunk.index.isin(keep_idx)]
        chunks.append(filtered_chunk)
    return pd.concat(chunks)

# 读取筛选后的完整数据
csv1_filtered = read_filtered_csv(csv1, keep_csv1_idx, primary_idx_list)
csv2_filtered = read_filtered_csv(csv2, keep_csv2_idx, primary_idx_list)

# 拼接并输出结果
result_df = pd.concat([csv1_filtered, csv2_filtered])
result_df.to_csv(...)

场景2:最终输出仅需保留索引列和目标列

如果你的结果不需要原CSV的全部字段,直接在阶段1结束后即可拼接输出,此时read_csv的耗时会降到最低:

# 拼接筛选后的轻量DataFrame
result_light_df = pd.concat([csv1_df_light.loc[keep_csv1_idx], csv2_df_light.loc[keep_csv2_idx]])
result_light_df.to_csv(...)

额外优化建议

  • 替换为C引擎:如果可以先通过命令行工具(如sed)去掉首尾行,建议将engine='python'改为engine='c',C引擎的读取速度远快于Python引擎(注意C引擎不支持skipfooter参数)。
  • 保持现有优化参数:你已经设置了dtype=str和keep_default_na=False,这能避免Pandas自动推断数据类型的额外开销,继续保持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:50:56