我的知识记录

Python CSV大数据分块读取教程:chunksize不爆内存

用pandas chunksize分块读取GB级CSV,逐块处理、聚合、导出,解决一次性读入内存不够的问题,附完整可运行代码。

场景痛点

拿到一份2GB的用户行为CSV,直接 pd.read_csv 内存直接占满,程序被杀掉;公司电脑只有8G内存,根本打不开这么大的表。其实不需要一次全读进来,分块读、逐块处理、最后聚合,几个G的文件照样跑得动。

用到的库

pip install pandas

完整代码

# 大数据CSV分块读取
import pandas as pd

def read_in_chunks(input_path, chunk_size=100000):
"""
分块读取CSV,每次读 chunk_size 行。
返回一个迭代器,每次给一个DataFrame。
"""
chunk_iter = pd.read_csv(
input_path,
chunksize=chunk_size,
encoding="utf-8-sig",
low_memory=False,  # 混合类型列时不报警
)
total_rows = 0
for i, chunk in enumerate(chunk_iter):
total_rows += len(chunk)
print(f"第 {i+1} 块:{len(chunk)} 行,累计 {total_rows}")
yield chunk

def aggregate_in_chunks(input_path, chunk_size=100000):
"""
边分块读边聚合,不需要把全表放内存。
示例:统计每个城市的总订单数和总金额。
"""
city_stats = {}  # {城市: {"count": x, "amount": y}}

for chunk in read_in_chunks(input_path, chunk_size):
for city, group in chunk.groupby("城市"):
if city not in city_stats:
city_stats[city] = {"count": 0, "amount": 0.0}
city_stats[city]["count"] += len(group)
city_stats[city]["amount"] += group["金额"].sum()

# 转成DataFrame输出
result = pd.DataFrame(city_stats).T.reset_index()
result.columns = ["城市", "订单数", "总金额"]
result = result.sort_values("总金额", ascending=False)
print("\n=== 各城市汇总 ===")
print(result)
result.to_csv("city_summary.csv", index=False, encoding="utf-8-sig")
return result

def filter_in_chunks(input_path, output_path, chunk_size=100000):
"""
分块筛选:每块里满足条件的行追加写到输出文件。
比如只要北京、上海的数据。
"""
first_chunk = True
for chunk in read_in_chunks(input_path, chunk_size):
mask = chunk["城市"].isin(["北京", "上海"])
sub = chunk[mask]
if len(sub) == 0:
continue
# 第一块写表头,后续追加不写表头
sub.to_csv(
output_path,
mode="w" if first_chunk else "a",
header=first_chunk,
index=False,
encoding="utf-8-sig",
)
first_chunk = False
print(f"分块筛选完成:{output_path}")

def main():
big_file = "big_data.csv"
# aggregate_in_chunks(big_file, chunk_size=200000)
filter_in_chunks(big_file, "beijing_shanghai.csv", chunk_size=200000)

if __name__ == "__main__":
main()

代码讲解

  • pd.read_csv(chunksize=100000) 返回迭代器,每次给你10万行的DataFrame,内存占用稳定。
  • 聚合场景:维护一个dict跨块累加,块之间不依赖,跑完就是全量统计。
  • 筛选场景:每块满足条件的行 to_csv(mode="a") 追加写,第一块才写表头。
  • low_memory=False 避免pandas对混合类型列报DtypeWarning。
  • chunk_size 按内存调:8G内存跑20万行一块比较稳,文件小就调大些。

运行结果

控制台逐块打印读取进度。聚合示例输出 city_summary.csv,按城市汇总订单数和总金额;筛选示例输出 beijing_shanghai.csv,只包含京沪数据。整个过程内存占用稳定在几十MB。

注意事项

  • 分块读时不能跨块排序、去重,这些操作需要全局,要么先排序再分块,要么用SQLite/DuckDB。
  • 跨块去重:维护一个已见key集合,边读边判断,内存占用和去重key数量成正比。
  • 列类型推断在每块独立做,可能导致类型不一致,读的时候指定 dtype 强制统一。
  • 真正超大(10GB+)建议用DuckDB或polars,比pandas分块更快更省内存。

Python CSV大数据分块读取教程:chunksize不爆内存

标签:

更新时间:2026-09-14 21:04:57

上一篇:Python CSV去重教程:按列或整行去重保留第一条

下一篇:Python批量读取多个JSON汇总教程