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

为何64GB内存无法将6.8GB CSV文件全量载入NumPy数组?

问题原因分析

嘿,我来帮你捋捋这个问题——你遇到的核心矛盾根本不是内存不够,而是np.genfromtxt的加载机制在偷偷吃掉大量额外内存:

  • genfromtxt解析CSV时,会先把整个文件读成一个巨型字符串数组,再逐行逐个字段转换为数值类型。这个过程会产生海量临时字符串对象和中间数组,实际内存峰值可能是最终NumPy数组的2~3倍甚至更多。哪怕你算出来最终数组只需要4.56G,解析时的内存占用可能直接冲到15G以上,要是系统还有其他进程占内存,很容易触发内存不足错误。
  • 另外Python的垃圾回收有延迟,临时内存没法及时释放,也会进一步加剧内存压力。
  • 还有个容易忽略的点:如果你用的是32位Python,哪怕系统有64G内存,它最多也只能用4G左右——不过你有64G内存,大概率是64位版本,但还是可以检查确认下。
解决办法

结合你要用于Keras训练的场景,我给你几个递进的解决方案:

1. 换用更高效的加载工具:Pandas

pandas.read_csv的内存效率和解析速度比np.genfromtxt强太多,它会直接按指定dtype处理数据,临时内存开销极小。示例代码:

import pandas as pd
import numpy as np

# 用字典指定每个字段的dtype,对应你之前的"i1,i1,f4..."设置
dtype_dict = {
    'col0': 'int8',
    'col1': 'int8',
    'col2': 'float32',
    # 剩下的128个字段依次对应你的类型设置
}

# 加载CSV(如果没有表头,加上header=None参数)
df = pd.read_csv('./data.csv', delimiter=';', dtype=dtype_dict, header=None)
# 转换为NumPy数组
data = df.to_numpy()

2. 提前转成二进制格式(一劳永逸)

如果之后还要反复用这个数组,建议把它转成NumPy的.npy二进制文件,后续加载时直接读二进制,完全没有解析开销:

# 加载后保存为npy文件
data = df.to_numpy()
np.save('./data.npy', data)

# 后续直接加载,速度极快,内存占用就是数组本身大小
data = np.load('./data.npy')

3. 分块加载+Keras数据生成器

要是还是碰到内存问题,或者你不想一次性把所有数据塞进内存(毕竟Keras训练本来就是分批次的),可以用分块读取+自定义Keras数据生成器:

import tensorflow as tf
from tensorflow.keras.utils import Sequence

class CSVDataGenerator(Sequence):
    def __init__(self, csv_path, delimiter=';', dtype_dict=None, batch_size=32):
        self.csv_path = csv_path
        self.delimiter = delimiter
        self.dtype_dict = dtype_dict
        self.batch_size = batch_size
        # 先统计总行数(有表头就减1,没有就去掉-1)
        with open(csv_path, 'r') as f:
            self.total_rows = sum(1 for _ in f) - 1

    def __len__(self):
        # 计算总批次
        return int(np.ceil(self.total_rows / self.batch_size))

    def __getitem__(self, idx):
        # 读取指定批次的数据
        skiprows = idx * self.batch_size + 1  # 有表头就+1,无表头则去掉
        df = pd.read_csv(
            self.csv_path,
            delimiter=self.delimiter,
            dtype=self.dtype_dict,
            skiprows=skiprows,
            nrows=self.batch_size,
            header=None
        )
        # 根据你的任务拆分特征和标签,这里示例只返回特征
        X = df.to_numpy()
        y = ...  # 替换成你的标签逻辑
        return X, y

# 使用生成器训练模型
generator = CSVDataGenerator('./data.csv', delimiter=';', dtype_dict=dtype_dict, batch_size=64)
model.fit(generator, epochs=10)

这种方式每次只加载一个批次的数据,内存占用极低,完美适配超大规模数据集训练。

4. 最后排查环境问题

  • 确认是64位Python:执行python -c "import sys; print(sys.maxsize > 2**32)",输出True就是64位。
  • 清理系统内存:加载前关掉不必要的进程,避免内存被其他程序占用过多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:39:58