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

如何避免Python读取大CSV时内存占满至100%导致系统冻结?

解决大CSV文件读取内存耗尽的问题

兄弟,我太懂你这种崩溃的感受了——16GB的CSV直接塞进内存,连64GB RAM都扛不住,系统直接原地冻结,重启都得等半天对吧?其实问题出在pandas默认会把整个文件加载到内存,而CSV转成DataFrame后实际占用的内存往往是原文件的2-5倍(因为pandas会给列分配更“安全”的数据类型),16GB的文件撑爆64GB内存完全不意外。

下面给你几个实用的解决方案,按易上手程度排序:

1. 分块读取+逐步处理

这是最直接的改进方式,用pandas的chunksize参数把文件拆成小块,每次只加载一部分到内存,处理完就释放空间:

import pandas as pd
from time import time

filename = 'AKER_OB.csv'
chunk_size = 10_000_000  # 每次读1000万行,可根据你的内存调整大小
timestamp_col = 'timestamp'  # 替换成你实际的时间戳列名
start_ = time()

# 存储每个排序后的块
sorted_chunks = []

# 分块读取并排序
for chunk in pd.read_csv(filename, chunksize=chunk_size, parse_dates=[timestamp_col]):
    # 对当前块按时间戳排序
    sorted_chunk = chunk.sort_values(by=timestamp_col)
    sorted_chunks.append(sorted_chunk)

# 合并所有块后再整体排序(如果合并后内存还够的话)
merged_df = pd.concat(sorted_chunks)
final_sorted_df = merged_df.sort_values(by=timestamp_col)

# 保存结果
final_sorted_df.to_csv('AKER_OB_sorted.csv', index=False)

end_ = time()
print(f"处理完成,耗时{end_ - start_:.2f}秒")

如果合并后的DataFrame还是太大,你可以把每个排序后的块先存成临时CSV,再用归并排序的方式合并(或者直接用下面的Dask工具)。

2. 指定数据类型减少内存占用

很多时候内存浪费是因为pandas默认的类型太“冗余”,比如把字符串列设为object,整数设为int64。手动指定更紧凑的类型能大幅降低内存占用:

# 先读一小部分数据查看列类型
sample_df = pd.read_csv(filename, nrows=1000)
print(sample_df.dtypes)

# 自定义类型映射,根据你的实际列调整
dtype_spec = {
    'id': 'int32',  # 如果数值范围不大,用int32代替int64
    'status': 'category',  # 重复值多的字符串列用category类型,能省80%以上内存
    'timestamp': 'datetime64[ns]'  # 直接解析为datetime,比存字符串更高效还方便排序
}

# 分块读取时应用类型
for chunk in pd.read_csv(filename, chunksize=chunk_size, dtype=dtype_spec, parse_dates=[timestamp_col]):
    # 排序逻辑同上...

3. 用Dask处理超大数据集

如果pandas的分块还是不够用,试试Dask——它是专门为超大数据集设计的并行计算库,用法和pandas几乎一致,但会自动在后台处理分块和内存管理:

import dask.dataframe as dd
from time import time

filename = 'AKER_OB.csv'
timestamp_col = 'timestamp'
start_ = time()

# 读取CSV,Dask自动分块
ddf = dd.read_csv(filename, parse_dates=[timestamp_col])
# 按时间戳排序(Dask会自动处理外部排序,不用管内存)
sorted_ddf = ddf.sort_values(by=timestamp_col)

# 保存结果,默认生成多个分块文件,加single_file=True可生成单个文件
sorted_ddf.to_csv('AKER_OB_sorted.csv', index=False, single_file=True)

end_ = time()
print(f"处理完成,耗时{end_ - start_:.2f}秒")

4. 用命令行工具快速搞定

如果不想写代码,直接用Linux的sort命令——它天生支持大文件的外部排序,速度快还不占多少内存:

# 假设时间戳在第3列(从1开始计数),用逗号分隔列
sort -t ',' -k3,3 AKER_OB.csv > AKER_OB_sorted.csv

如果你的时间戳是字符串格式,可能需要加-V参数按版本号排序(比如处理带日期的字符串):

sort -t ',' -k3,3 -V AKER_OB.csv > AKER_OB_sorted.csv

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:23:32