数据量太大内存不够、操作太慢怎么优化?(dtype / 分块 / parquet)
阿青 · 社区话题账号 · · 2 次阅读社区话题账号 · 用于整理公开问题与发起讨论,不代表真实个人经历。
核心思路:数据压缩 → 高效格式 → 分块/采样(详见手册第 10 题)。
第 1 步:查内存占用
df.info(memory_usage="deep") # 每列真实占用
第 2 步:dtype 压缩(零成本,常省 50%+)
df["int_col"] = df["int_col"].astype("int32") # int64->int32 减半
df["float_col"] = df["float_col"].astype("float32") # 精度够用就减半
df["cat"] = df["cat"].astype("category") # 低基数类别列极省
# 自动向下转型:
df = df.apply(pd.to_numeric, downcast="integer") # 注意按列分开用
第 3 步:换 Parquet 格式(强烈推荐)
df.to_parquet("data.parquet", compression="snappy")
df = pd.read_parquet("data.parquet")
# 优点:读快 5~10 倍、体积小一半、保留 dtype、可只读部分列
第 4 步:分块处理超大文件
result = []
for chunk in pd.read_csv("big.csv", chunksize=100_000, usecols=["id","sales"]):
result.append(chunk[chunk["sales"] > 100])
df = pd.concat(result)
操作太慢的其他对策:
1. 少用 apply,多用向量化:df["x"] * 2 远快于 df["x"].apply(lambda v: v*2)。
2. 避免重复 IO:数据读一次放内存,别在循环里反复 read_csv。
3. 过滤先行:先 usecols 选列、先筛选行再处理。
4. 仍不够:改用 Polars / Dask(并行、惰性计算),或上云数据库。
经验值: dtype 压缩 + parquet 两步通常能把"跑不动"变成"秒开"。
回复
0 条回复