DevCN
菜单
讨论动态发现圈子我关注的我的收藏
# Python

Python AI 实战(10/20):数据量太大内存不够怎么办?Pandas 分块读取与内存优化

阿青 · 社区话题账号 · · 3 次阅读

社区话题账号 · 用于整理公开问题与发起讨论,不代表真实个人经历。

Python AI 实战问答速查手册 · 第 10/20 问

所属板块:数据处理

先诊断内存占用,再对症下药:

df.info(memory_usage="deep")      # 看每列真实内存占用

方案一:压缩数据类型(收益取决于原始类型和取值)

df["int_col"] = df["int_col"].astype("int32")    # int64 -> int32
df["float_col"] = df["float_col"].astype("float32")
df["cat_col"] = df["cat_col"].astype("category") # 类别列:少量类别时极省内存
# 有符号/无符号小整数:int8 可表示 -128~127,按取值范围选最小类型

整数可用 pd.to_numeric(s, downcast="integer"),浮点数可用 pd.to_numeric(s, downcast="float")。直接 astype 前检查取值范围和精度要求,避免整数溢出或浮点误差。

方案二:分块读取(文件太大无法一次性装入时)

import pandas as pd

count = 0
for chunk in pd.read_csv("big.csv", usecols=["price"], chunksize=100_000):
  price = pd.to_numeric(chunk["price"], errors="coerce")
  count += int(price.gt(100).sum())
print("price 大于 100 的行数:", count)
# 每块只保留聚合结果,不把所有块累积到列表里再 concat。
# 如需保留筛选后的明细,可逐块写出到文件或数据库。

方案三:换高效存储格式(强烈推荐)

  • Parquet:列式存储,适合压缩和按列读取,速度与体积收益需用实际数据比较:
df.to_parquet("data.parquet")
df = pd.read_parquet("data.parquet")   # 只读部分列也很快
  • HDF5:适合科学计算大数组。

  • 日常分析完导出数据,优先存 parquet 而非 csv。

方案四:其他技巧

  • 先采样再分析:探索阶段 df.sample(min(len(df), 100_000)) 够用就别读全量。

  • 内存映射pd.read_csv(..., memory_map=True) 可映射文件进行读取,但不能让最终 DataFrame 不占内存。

  • 分列加载:需要哪些列分多次读。

  • 实在装不下:升级思路——用 Dask / Polars 的适用执行模式(并非所有操作都能流式或处理超内存数据),或干脆用云数据库/Spark。

一句话总结:先 检查 dtype 并谨慎压缩→ 用 parquet 存储 → 实在大就 chunksize 分块 + 采样。

教程
REPLIES

回复

0 条回复
暂无回复。