如何不加载全量文件为现有CSV/Parquet文件新增列?
实现可行性说明
CSV是行式存储的纯文本格式,本身不支持原地新增列,但是可以通过流式逐行读写的方式,全程不加载全量数据到内存完成新增列操作,内存开销仅和单行长、分块大小有关,完全符合你的需求。
对应示例场景的实现代码
你已经提前计算得到和原文件行数完全对齐的main_col['new_col'],可以直接用Python内置csv模块流式处理:
import csv import os # 将新列转为迭代器,减少额外内存占用 new_col_iter = iter(main_col['new_col'].tolist()) # 同时打开原文件读、临时文件写 with open('./the_file.csv', 'r', encoding='utf-8') as in_file, \ open('./temp_the_file.csv', 'w', encoding='utf-8', newline='') as out_file: csv_reader = csv.reader(in_file) csv_writer = csv.writer(out_file) # 处理表头:追加新列名 header = next(csv_reader) header.append('new_col') csv_writer.writerow(header) # 逐行处理:读一行原数据,追加对应新列值,写入临时文件,全程不加载全量数据 for row in csv_reader: row.append(str(next(new_col_iter))) csv_writer.writerow(row) # 处理完成后用临时文件替换原文件(可选,也可直接保留临时文件作为结果) os.replace('./temp_the_file.csv', './the_file.csv')
进阶优化(新列也无需提前全量计算)
如果新列的计算不需要依赖全量数据,可以直接结合Pandas分块读取能力,连新列都不需要全量存入内存,进一步降低资源开销:
import csv import os import pandas as pd # 按内存容量调整分块大小,比如每次读取10000行处理 CHUNK_SIZE = 10000 with open('./the_file.csv', 'r', encoding='utf-8') as in_file, \ open('./temp_the_file.csv', 'w', encoding='utf-8', newline='') as out_file: csv_reader = csv.reader(in_file) csv_writer = csv.writer(out_file) # 写入表头 header = next(csv_reader) header.append('new_col') csv_writer.writerow(header) # 分块读取指定列计算,逐行追加 for chunk in pd.read_csv('./the_file.csv', usecols=['col1'], chunksize=CHUNK_SIZE): chunk['new_col'] = chunk['col1'] / 2 for new_val in chunk['new_col']: row = next(csv_reader) row.append(str(new_val)) csv_writer.writerow(row) os.replace('./temp_the_file.csv', './the_file.csv')
注意事项
- 必须保证新列的行数和原文件数据行数完全一致,否则会出现行列错位问题
- 如果是其他格式的文件处理逻辑有区别:
- Excel同样为行存储,超大文件可以用
openpyxl的只读/只写流式模式实现,逻辑和CSV处理一致 - Parquet为列存储格式,原生支持追加列,无需全量读取,可直接用
pyarrow的API实现,内存开销更低
- Excel同样为行存储,超大文件可以用
内容的提问来源于stack exchange,提问作者wildcat89
相关产品推荐
相关产品推荐

