当处理超大型CSV文件时,使用`pd.read_csv(..., chunksize=...)`进行分块读取是优化内存的有效方法。以下是分块读取的详细实现方案和注意事项:
### **分块读取核心代码框架**
```python
import pandas as pd
# 定义分块大小(根据内存调整,例如10MB~100MB/块)
chunk_size = 10_000 # 每块1万行,或按内存计算:可用内存MB * 1000 / 每行字节数
# 分块读取(返回迭代器)
chunk_iterator = pd.read_csv("large_file.csv", chunksize=chunk_size)
# 逐块处理
for chunk in chunk_iterator:
# 示例处理:筛选+统计
filtered = chunk[chunk['value'] > 100]
result = filtered.groupby('category')['value'].sum()
# 累积结果(避免内存爆炸)
if 'final_result' not in locals():
final_result = result
else:
final_result += result
# 输出最终结果
print(final_result)
```
### **关键优化技巧**
1. **动态调整分块大小**
```python
# 根据可用内存自动计算分块大小(假设每行1KB,保留20%内存冗余)
import psutil
available_memory = psutil.virtual_memory().available * 0.8 # 字节
chunk_size = available_memory // (1024 * 1) # 每行1KB
```
2. **类型强制转换**
```python
# 读取时指定列类型减少内存占用
chunk_iterator = pd.read_csv(..., dtype={'id': 'int32', 'timestamp': 'datetime64[ns]'})
```
3. **并行处理加速**
```python
from multiprocessing import Pool
def process_chunk(chunk):
return chunk[chunk.value > 100].groupby('category').sum()
with Pool(4) as p: # 4进程并行
results = p.map(process_chunk, chunk_iterator)
final_result = pd.concat(results).groupby(level=0).sum()
```
4. **增量式保存结果**
```python
# 分块处理后立即写入磁盘(避免内存累积)
for i, chunk in enumerate(chunk_iterator):
processed = chunk.process()
processed.to_parquet(f"temp_{i}.parquet", index=False)
# 最终合并
final_df = pd.concat([pd.read_parquet(f) for f in temp_files], ignore_index=True)
```
### **适用场景与限制**
- **适合场景**:
- 文件大小超过可用内存(如10GB+文件)
- 只需聚合统计(sum/count/avg等)
- 可分块独立处理的逻辑
- **不适用场景**:
- 需要全局排序/去重
- 依赖跨块计算的窗口函数
- 需要随机访问特定行
### **进阶方案对比**
| 方法 | 内存占用 | 处理速度 | 复杂度 | 适用场景 |
|---------------------|----------|----------|--------|------------------------|
| 分块读取+Pandas | 低 | 中 | 简单 | 聚合统计 |
| Dask DataFrame | 低 | 高 | 中 | 复杂转换+分布式计算 |
| Vaex | 极低 | 极高 | 较高 | 超大规模数据集(TB级) |
| 数据库导入 | 最低 | 慢 | 高 | 一次性处理+后续查询 |
建议根据数据规模(GB/TB级)和处理需求选择工具。对于TB级数据,推荐结合`pyarrow`使用分块读取+Parquet格式存储中间结果。