Pandas导出CSV为何自动追加?两种写入方式内存差异解析
多TXT合并CSV代码疑问解答
现有可运行代码
import pandas as pd import glob import csv import os col_lengths = {'Column1': range(0, 2), 'Column2': range(3, 11), } col_lengths = {k: set(v) for k, v in col_lengths.items()} path = r"C:\myfolder" all_files = glob.glob(os.path.join(path, "*.txt")) with open(os.path.join(path, "output_file.csv"), "wb") as f: for i, filename in enumerate(all_files): print(filename) df = pd.read_fwf( filename, colspecs=[(min(x), max(x)+1) for x in col_lengths.values()], header=None, names=col_lengths, converters={'Column1':lambda x : str(x), 'Column2':lambda x : str(x), } ) df.to_csv( f, header=(i == 0), sep=";", decimal=",", mode="wb", quoting=csv.QUOTE_MINIMAL)
问题1:外层使用with open("wb")打开文件,为何df.to_csv会自动追加数据而非覆盖?若去掉外层with open循环写入,是否每次都会覆盖文件最终仅保留最后一个文件的数据?
- 外层用
with open("wb")打开文件后,文件对象f处于持续打开的写入状态,文件指针会随着每次写入自动移动到文件末尾。df.to_csv接收这个已打开的文件对象时,会直接在当前指针位置写入内容,自然形成追加效果。这里df.to_csv里的mode="wb"是无效的——因为文件已经以wb模式打开,to_csv在传入文件对象时会忽略mode参数。 - 如果去掉外层
with open,改成循环里每次调用df.to_csv直接指定输出文件路径,且用mode="wb"的话,每次打开文件都会清空原有内容再写入,最终只会保留最后一个文件的数据;如果改成mode="ab"才会实现追加,但这属于另一种写法逻辑。
问题2:对比两种写入方式:外层with open持续写入vs df.to_csv使用append模式,在处理大文件、内存有限的场景下有何差异?比如append模式每次打开大文件是否会引发内存错误,而持续打开文件写入为何不会?大文件是否会占用过多内存?
- 内存占用核心逻辑:两种写法本质都是逐文件读取处理后写入,内存占用主要取决于单个TXT文件转成DataFrame的大小,和写入方式无关——不管哪种写法,都是处理完一个文件就把数据写入磁盘,不会把所有文件的数据都存在内存里。
- 文件操作效率差异:
- 外层持续打开文件的方式:只需要执行1次文件打开/关闭操作,减少了重复打开大文件的IO开销,尤其当输出CSV文件很大时,反复打开关闭会浪费系统资源,但不会引发内存错误——打开文件只是创建一个文件描述符,不会把整个文件加载到内存。
df.to_csv用append模式(mode="a"):每次循环都要打开一次输出文件,写完再关闭。虽然不会加载整个文件到内存,但频繁的打开/关闭操作会增加IO耗时,当待处理的TXT文件数量很多时,效率会比持续打开的方式低。
- 两种方式都不会因为输出文件大而引发内存错误,因为写入都是流式的,DataFrame的数据是分批写入磁盘,不会把整个输出CSV加载到内存中。
内容的提问来源于stack exchange,提问作者PSt
相关产品推荐
相关产品推荐

