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

拼接百万级CSV生成Pandas DataFrame遇内存错误,求优化方案

解决方案:处理大CSV拼接的内存问题

嘿,我来帮你搞定这个内存溢出的问题!首先先指出你现有代码里的两个关键小问题,再给几个针对大数据拼接的优化方案——毕竟10个百万行级别的CSV,确实容易吃满内存~

先修正代码里的基础错误

你当前的代码有两个明显问题,先搞定它们:

  • 循环里pd.read_csv('file')用了字符串'file',应该是变量file,不然每次都在读一个名叫"file"的文件(甚至会直接报错);
  • 你现在的循环每次都把df覆盖成当前文件的DataFrame,最后pd.concat(df,...)其实只拼接了最后一个文件,根本没把所有文件合起来!正确的做法是把每个df存到列表里再拼接(不过这只是语法修正,内存问题还要靠后面的方案)。

修正后的基础版代码(但还是可能内存不够):

import pandas as pd

df_list = []
for file in filenames:
    df = pd.read_csv(file, sep=',', encoding='utf-8', dtype='object')
    df_list.append(df)
    print(f"已加载 {file},行数:{len(df)}")

concatenated_df = pd.concat(df_list, ignore_index=True)

针对内存问题的优化方案

上面的基础版会把所有10个DataFrame全加载到内存,所以会触发MemoryError。结合你32GB内存的配置,这些方案更实用:

1. 分块读取+逐块拼接

不用一次性加载整个文件,用chunksize参数分批次读取,每读一块就拼接到结果里,大幅降低内存峰值:

import pandas as pd

# 初始化空的结果DataFrame
concatenated_df = pd.DataFrame()

for file in filenames:
    # 分块读取,比如每次读10万行(可根据内存情况调整)
    chunk_iter = pd.read_csv(file, sep=',', encoding='utf-8', dtype='object', chunksize=100000)
    for chunk in chunk_iter:
        concatenated_df = pd.concat([concatenated_df, chunk], ignore_index=True)
        print(f"已添加 {file} 的数据块,当前总行数:{len(concatenated_df)}")

这种方式每次内存里只保留一小块数据,能有效避免内存溢出。

2. 只读取必要的列

如果业务不需要CSV里的所有列,一定要用usecols参数指定只加载需要的列,直接砍掉不必要的内存占用:

# 假设你只需要col1、col3、col5这三列
needed_cols = ['col1', 'col3', 'col5']

concatenated_df = pd.DataFrame()
for file in filenames:
    chunk_iter = pd.read_csv(
        file, 
        sep=',', 
        encoding='utf-8', 
        usecols=needed_cols, 
        dtype='object', 
        chunksize=100000
    )
    for chunk in chunk_iter:
        concatenated_df = pd.concat([concatenated_df, chunk], ignore_index=True)

3. 优化数据类型(关键!)

你现在用dtype='object'会让所有列都存成Python对象,这是非常占内存的。针对不同列指定更高效的数据类型,能把内存占用降到原来的1/5甚至更低:

  • 字符串列:重复值多就用category类型;重复少但格式固定用string类型(pandas 1.0+支持);
  • 数值列:用最小能容纳范围的类型,比如int32代替int64,float32代替float64;
  • 日期列:用parse_dates参数直接解析成datetime64类型,比存字符串省内存。

示例代码:

# 自定义数据类型映射
dtype_map = {
    'id': 'int32',
    'category_col': 'category',
    'value': 'float32',
    'name': 'string'
}

concatenated_df = pd.DataFrame()
for file in filenames:
    chunk_iter = pd.read_csv(
        file, 
        sep=',', 
        encoding='utf-8', 
        dtype=dtype_map,
        parse_dates=['date_col'],  # 自动解析日期列
        chunksize=100000
    )
    for chunk in chunk_iter:
        concatenated_df = pd.concat([concatenated_df, chunk], ignore_index=True)

4. 使用Dask DataFrame(终极方案)

如果上面的方法还是不够,试试Dask——它专门处理超出内存的大数据,用法和pandas几乎一致,但会延迟计算,不用把所有数据加载到内存:

import dask.dataframe as dd

# 用Dask读取所有CSV
ddf = dd.read_csv(filenames, sep=',', encoding='utf-8', dtype='object')

# 执行拼接(Dask会延迟计算,直到调用compute())
concatenated_df = ddf.compute()  # 如果内存还是紧张,可以不用转成pandas,直接用Dask处理数据

Dask会自动分块处理,32GB内存应付10个百万行CSV完全没问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:07:27