用Python处理超大CSV文件:内存不够用?这招帮你搞定
嗨,小伙伴们,大家好啊!今天咱们来看一个特别实用的话题:如何处理那些大到爆炸的 CSV 文件。Boss摔给你一个任务:10GB 的用户购物记录 CSV 文件,让你统计每个用户的总消费金额。但当你兴冲冲地用 pandas 打开文件时...电脑内存不够用了!这可咋整?
为啥会遇到这个问题?
传统的做法(比如用 pandas)会一次性把整个文件加载到内存中。这就像你想把一头大象塞进小面包车 —— 那当然塞不进去啊!
解决方案:分批次读取处理!
就像搬家时把大象切成小块运输一样,我们可以把大文件分成小块来处理。Python 提供了一个特别好用的工具:csv 模块。
先来看看具体怎么做:
import csv
from collections import defaultdict
def process_large_csv(filename):
# 用字典存储每个用户的消费总额
user_totals = defaultdict(float)
# 打开文件,开始逐行处理
with open(filename, 'r') as file:
# 创建 CSV 读取器
csv_reader = csv.DictReader(file)
# 逐行处理数据
for row in csv_reader:
user_id = row['user_id'] # 假设CSV中有user_id列
amount = float(row['amount']) # 假设CSV中有amount列
user_totals[user_id] += amount
return user_totals
# 使用示例
filename = 'huge_shopping_records.csv'
results = process_large_csv(filename)
# 打印前5个用户的消费总额
for user_id, total in list(results.items())[:5]:
print(f"用户 {user_id} 总消费: yen{total:.2f}")
想处理得更快?来个进度条!
from tqdm import tqdm # 需要先 pip install tqdm
def process_large_csv_with_progress(filename):
user_totals = defaultdict(float)
# 先数一下总行数
total_rows = sum(1 for _ in open(filename)) - 1 # 减去标题行
with open(filename, 'r') as file:
csv_reader = csv.DictReader(file)
# 添加进度条,让处理过程可视化
for row in tqdm(csv_reader, total=total_rows, desc="处理进度"):
user_id = row['user_id']
amount = float(row['amount'])
user_totals[user_id] += amount
return user_totals
为什么这种方法这么棒
- 超级省内存:一次只读一行数据,就像用小勺子一口一口吃大象
- 速度够快:虽然不如 pandas 一次性加载快,但胜在稳定可靠
- 简单易用:代码简单,容易理解和修改
实用技巧
- 处理脏数据:
def safe_float_convert(value):
try:
return float(value)
except (ValueError, TypeError):
return 0.0
# 在处理数据时使用
amount = safe_float_convert(row['amount'])
- 定期保存中间结果:
# 每处理10万行保存一次结果
if csv_reader.line_num % 100000 == 0:
with open('intermediate_results.txt', 'w') as f:
for user_id, total in user_totals.items():
f.write(f"{user_id},{total}\n")
总结
这个技巧特别适合处理:
- 用户行为日志
- 交易记录数据
- 传感器采集数据
- 网站访问日志 ...等等各种大文件!
如果数据量特别大,考虑用多进程处理,记得处理异常情况哦,这就像是把大象分成小块处理的智慧 —— 不求一次性搞定,但求稳扎稳打,分批处理才是王道。有问题尽管在评论区问我,一起学习进步!