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

Python使用pd.merge合并大CSV报MemoryError内存错误问题求助

问题根因

触发527G内存报错和设备性能无关,核心是两个CSV的连接键isin存在大量重复值,pd.merge执行内连接时会对重复键做全量笛卡尔匹配,最终生成37亿行的无效中间结果,远超出64G内存承载上限。

分步落地方案

第一步:优先排查并清理重复键(90%的场景可直接解决问题)

金融场景下isin是证券类资产的唯一编码,正常单条资产记录对应唯一isin,出现天量匹配结果基本都是源文件存在重复数据导致的,先做这一步,不要上来就换工具。
直接复制运行以下代码,全程内存占用不超过1G,可快速定位重复问题:

import pandas as pd

# 仅读取两个文件的isin列,不加载全量数据
isin_col1 = pd.read_csv("替换为你的第一个CSV文件完整路径.csv", usecols=['isin'])
isin_col2 = pd.read_csv("替换为你的第二个CSV文件完整路径.csv", usecols=['isin'])

# 打印重复情况统计
print(f"表1 isin总记录数:{len(isin_col1)}")
print(f"表1 去重后isin数量:{isin_col1['isin'].nunique()}")
print(f"表2 isin总记录数:{len(isin_col2)}")
print(f"表2 去重后isin数量:{isin_col2['isin'].nunique()}")

如果输出结果里去重后的isin数量远小于总记录数,说明存在重复行,先按业务规则去重再合并,参考代码如下(可直接修改列名后运行):

# !!!重要:只读取你实际需要用到的列,不要加载无关字段,至少能省60%内存
# 把下面列表里的内容替换成你要保留的列名即可
need_cols1 = ['isin', '需要保留的表1字段1', '需要保留的表1字段2', '需要保留的表1字段3']
need_cols2 = ['isin', '需要关联带出的表2字段1', '需要关联带出的表2字段2']

# 加载需要的字段,同时指定isin为字符串类型,避免匹配错误
data1 = pd.read_csv("替换为你的第一个CSV文件完整路径.csv", 
                    usecols=need_cols1, 
                    dtype={'isin': 'string'})
data2 = pd.read_csv("替换为你的第二个CSV文件完整路径.csv", 
                    usecols=need_cols2, 
                    dtype={'isin': 'string'})

# 去重:如果同个isin存在多条完全重复的行,直接去重;如果是同个isin对应多时间点记录,按业务规则筛选
# 示例:同isin保留最后一条记录,可根据需求修改keep参数
data1 = data1.drop_duplicates(subset='isin', keep='last')
data2 = data2.drop_duplicates(subset='isin', keep='last')

# 执行合并,此时数据量会回归正常水平,不会触发内存错误
final_data = pd.merge(data1, data2, on='isin', how='inner')

# 导出结果,index=False表示不导出行号
final_data.to_csv("合并完成结果.csv", index=False)

第二步:业务确需保留isin下多条记录的低内存合并方案

如果你要做的是类似「isin对应的多日行情数据+isin对应的静态基本面数据」这类关联,单isin确实对应多条记录,不需要去重,就用Dask框架做内存调度,语法和pandas几乎一致,不需要改原有逻辑,64G内存完全可以支撑。
操作步骤:

  1. 安装依赖:打开终端/命令提示符,执行以下命令:
    pip install dask[dataframe]
  2. 复制运行以下代码,替换文件路径即可:
import dask.dataframe as dd
import dask

# 限制程序最大用50G内存,预留10G给系统运行,避免死机
dask.config.set({"memory_limit": "50GB"})

# 加载两个CSV文件,指定isin为字符串类型
ddf1 = dd.read_csv("替换为你的第一个CSV文件完整路径.csv", dtype={'isin': 'string'})
ddf2 = dd.read_csv("替换为你的第二个CSV文件完整路径.csv", dtype={'isin': 'string'})

# 内连接,语法和pandas完全一致
final_ddf = dd.merge(ddf1, ddf2, on='isin', how='inner')

# 导出为单个CSV文件,自动做分块内存调度,不会爆内存
final_ddf.to_csv("合并完成结果.csv", index=False, single_file=True)
避坑提醒
  • 不要用Excel打开几百M以上的CSV文件,会直接卡死,用VS Code或者Notepad++查看前几行确认列名即可。
  • 读文件时必须指定isin为字符串类型,否则框架会自动把编码识别为数字,不仅容易出现匹配错误,还会额外占用内存。
  • 无关字段一律不要读入内存,比如冗余的备注列、临时统计列,加载的列越少,合并速度越快,内存占用越低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:21:35