用pandas生成百万行csv时必须设index=false,可提速3.2倍、减容40%;应预分配列表一次性构造dataframe,避免循环append;字符串用np.random.choice,字段用category/int32优化类型。

用 pandas.DataFrame.to_csv() 生成百万行数据前必须关掉索引
默认开启的 index=True 会让每行多写一列序号,不仅文件体积翻倍(尤其字段少时),还会显著拖慢写入速度。实测 200 万行、5 列字符串数据,index=False 比默认快 3.2 倍,文件小 40%。
- 务必显式传参:
df.to_csv("data.csv", index=False) - 如果后续需要行号,用
pd.read_csv(..., index_col=False)读取更安全 - 避免先生成带索引的 DataFrame 再
reset_index(drop=True)—— 多一次内存拷贝
别用 for 循环逐行 append,改用预分配列表 + pd.DataFrame 构造
循环中反复调用 df.append() 或 pd.concat() 是性能杀手:每次触发完整 DataFrame 复制,200 万行可能卡死或 OOM。预分配 Python 列表再一次性构造,是唯一靠谱做法。
- 示例:生成 300 万行模拟用户数据
import pandas as pd
import numpy as np
<p>n = 3_000_000
data = {
"user_id": np.random.randint(1e6, 1e7, n),
"name": np.random.choice(["Alice", "Bob", "Charlie", "Diana"], n),
"age": np.random.randint(18, 80, n),
"city": np.random.choice(["Beijing", "Shanghai", "Guangzhou", "Shenzhen"], n),
}
df = pd.DataFrame(data) # 一次性构造,非循环拼接
df.to_csv("users.csv", index=False)</p>
- 字符串字段用
np.random.choice()预生成数组,比random.choice()快 10x+ - 避免在循环里调用
str.format()或f""拼接 —— 字符串对象创建开销极大
to_csv() 的 chunksize 不是为“流式写入”设计的,而是为“分块读取”准备的
很多人误以为设置 chunksize=10000 能边生成边写入节省内存,其实 to_csv() 根本不支持 chunked write。它只在 pd.read_csv() 中生效。真要控制内存,得手动分批构造 + 追加写入。
- 正确做法:按批次生成 DataFrame,用
mode="a"和header=False追加 - 首块写入时保留 header,后续块跳过 header,否则 CSV 会乱
- 示例关键逻辑:
with open("batched.csv", "w") as f:
first = True
for i in range(0, n, batch_size):
batch = generate_batch(i, i + batch_size)
df = pd.DataFrame(batch)
df.to_csv(f, index=False, header=first, mode="a")
first = False
- 注意:频繁磁盘追加仍比单次写入慢,仅在内存不足(如生成 1000 万行+)时才启用
- 别用
open(...).write(...)手动拼 CSV 字符串 —— 缺失转义、引号处理,极易出错
字段类型选错会让文件变大 3–5 倍,category 和 int32 是关键
默认 object 类型存字符串、int64 存整数,对测试数据纯属浪费。比如城市字段只有 4 个取值,用 category 可压缩 90% 内存;年龄用 int32 足够,省一半空间。
- 生成后立刻转换类型:
df["city"] = df["city"].astype("category")
df["age"] = df["age"].astype("int32")
- 数值字段慎用
float64—— 测试数据通常不需要小数精度,int32或float32更省 - 时间字段若只是占位,用字符串(如
"2024-01-01")比datetime64轻量得多 - 导出前检查:
df.info(memory_usage="deep")看真实内存占用
生成千万级文件时,最易被忽略的是磁盘 I/O 缓冲和临时内存峰值——哪怕你用了预分配和类型优化,to_csv() 内部仍会做字符串编码和缓冲区 flush。建议在 SSD 上操作,且留出至少 2 倍于最终文件大小的空闲内存。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











