按首列值拆分CSV文件仅首个文件生成正常的问题排查
问题分析与解决方案
你的代码核心问题出在最后一组数据的写入逻辑:循环结束后i的值是len(rows)-2,当最后一个地点对应的行只有1行时,rows[row_cur:i+1]会变成空切片(比如row_cur = len(rows)-1,i+1 = len(rows)-1,切片范围是[len(rows)-1 : len(rows)-1],即空列表),导致生成空白文件。
同时,原代码没有处理表头写入(如果需要每个拆分文件都包含表头的话),且一次性读取所有行到内存,不适用于大CSV文件。
修复后的原逻辑代码(适合小文件)
针对你的原有代码,只需修改最后一组数据的写入范围,并添加表头写入逻辑(可选):
import csv filepath = "你的输入文件路径.csv" with open(filepath) as csv_file: csv_reader = csv.reader(csv_file) rows = list(csv_reader) if not rows: exit() # 空文件直接退出 header = rows[0] row_cur = 1 loc_cur = rows[1][0] filecount = 0 for i in range(len(rows)-1): if rows[i+1][0] != loc_cur: print(f"{loc_cur} != {rows[i+1][0]}") with open(f"{filecount}_{loc_cur}.csv", 'w', newline='') as output: print(f"creating file: {output.name} from rows {row_cur} to {i}") csv_output = csv.writer(output) csv_output.writerow(header) # 若不需要表头可删除此行 csv_output.writerows(rows[row_cur:i+1]) row_cur = i+1 loc_cur = rows[row_cur][0] filecount += 1 # 处理最后一组数据:用rows[row_cur:]替代依赖i的切片 with open(f"{filecount}_{loc_cur}.csv", 'w', newline='') as output: print(f"creating file: {output.name} from rows {row_cur} to {len(rows)-1}") csv_output = csv.writer(output) csv_output.writerow(header) # 若不需要表头可删除此行 csv_output.writerows(rows[row_cur:])
高效逐行处理版本(适合大文件)
如果你的CSV文件较大,不建议一次性读取所有行到内存,改用逐行处理的方式,自动按地点创建文件并写入数据:
import csv filepath = "你的输入文件路径.csv" # 存储每个地点对应的文件句柄和CSV写入器 file_map = {} writer_map = {} try: with open(filepath, 'r', newline='') as infile: reader = csv.reader(infile) header = next(reader) # 读取表头 for row in reader: location = row[0] # 若该地点的文件未创建,则新建并写入表头 if location not in file_map: fh = open(f"{location}.csv", 'w', newline='') file_map[location] = fh writer = csv.writer(fh) writer.writerow(header) writer_map[location] = writer # 写入当前行到对应文件 writer_map[location].writerow(row) finally: # 确保所有打开的文件都被关闭 for fh in file_map.values(): fh.close()
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

