如何使用Python重新格式化超大单行CSV文件,实现每9个分隔符后换行以适配表格软件导入
如何使用Python重新格式化超大单行CSV文件,实现每9个分隔符后换行以适配表格软件导入
嘿,这个问题我碰到过类似的场景!先给你划重点:如果是超大文件,优先用Python内置的csv模块或者流式处理方案,别用pandas——因为pandas会把整个数据集加载到内存里,大文件很容易导致内存溢出,程序直接崩溃。下面给你三种靠谱的实现方案,按需选择:
方案一:基础分割法(适合大多数场景,代码直观)
如果文件没有大到离谱(内存能装下所有字段),直接把内容按分隔符分割成字段列表,再按每9个一组重新写入就行,代码简单易懂:
input_file = "你的输入文件.csv" output_file = "格式化后的文件.csv" # 定义每行的字段数量 fields_per_row = 9 with open(input_file, "r", encoding="utf-8") as infile, open(output_file, "w", encoding="utf-8") as outfile: # 读取整个单行内容 content = infile.read().strip() # 按分号分割所有字段 all_fields = content.split(";") # 先写入表头(前9个字段) outfile.write(";".join(all_fields[:fields_per_row]) + "\n") # 遍历剩下的字段,每9个一组写入新行 for i in range(fields_per_row, len(all_fields), fields_per_row): # 截取当前行的字段,最后一行可能不足9个也没关系 current_row = all_fields[i:i+fields_per_row] outfile.write(";".join(current_row) + "\n")
方案二:CSV模块规范处理(支持字段内包含分号的情况)
如果你的CSV里存在字段内容本身带分号的情况(比如字段是"张三;李四"),直接用split会把字段拆坏,这时候用Python内置的csv模块来处理更健壮,它能自动识别带引号的分隔符:
import csv input_file = "你的输入文件.csv" output_file = "格式化后的文件.csv" fields_per_row = 9 with open(input_file, "r", encoding="utf-8") as infile, open(output_file, "w", encoding="utf-8", newline="") as outfile: # 创建CSV读取器,指定分隔符和引号符 reader = csv.reader(infile, delimiter=";", quotechar='"') # 读取唯一的一行,得到所有字段的列表 all_fields = next(reader) # 创建CSV写入器,保持和原文件一致的格式 writer = csv.writer(outfile, delimiter=";", quotechar='"') # 写入表头 writer.writerow(all_fields[:fields_per_row]) # 按每9个字段一组写入数据行 for i in range(fields_per_row, len(all_fields), fields_per_row): writer.writerow(all_fields[i:i+fields_per_row])
方案三:流式处理(适合GB级超大文件,极致省内存)
如果文件大到连加载所有字段到内存都做不到(比如几十GB),可以用逐字符/分块读取的方式,边读边统计分隔符数量,每凑够9个字段就换行,全程内存占用极低:
input_file = "你的输入文件.csv" output_file = "格式化后的文件.csv" fields_per_row = 9 delimiter = ";" field_counter = 0 with open(input_file, "r", encoding="utf-8") as infile, open(output_file, "w", encoding="utf-8") as outfile: while True: # 每次读取4KB的内容块,避免一次性加载大文件 chunk = infile.read(4096) if not chunk: break for char in chunk: outfile.write(char) if char == delimiter: field_counter += 1 # 每9个字段对应8个分隔符,所以计数器到8时换行并重置 if field_counter == fields_per_row - 1: outfile.write("\n") field_counter = 0
关于pandas的补充说明
不是说pandas完全不能用,如果你文件不大,用pandas一行代码也能搞定,但对于超大文件来说绝对不推荐。比如小文件的pandas写法:
import pandas as pd df = pd.read_csv("你的输入文件.csv", sep=";", header=None) # 把单行数据转成每9列一行的格式,前9列作为表头 formatted_df = pd.DataFrame(df.values.reshape(-1, 9)) formatted_df.to_csv("格式化后的文件.csv", sep=";", index=False, header=False)
但这个方法会把整个文件加载到DataFrame里,大文件内存压力极大,所以还是优先前面的方案。
备注:内容来源于stack exchange,提问作者Gabs




