如何用Python(csv writer/pandas)将单列文本生成笛卡尔积形式CSV?
问题描述
现有单列文本文件drug_list.txt,内容示例:
A B C D
希望用Python生成双列CSV文件,包含所有元素的笛卡尔积,预期输出格式:
A,A A,B A,C A,D B,A B,B B,C B,D ...
用户尝试两步操作后得到错误输出:
- 生成重复第一列的代码:
import csv with open(r'C:\Users\soso-\Desktop\SVM\DataSet\drug_list.txt') as f: with open('integrated_x.csv', 'w') as out_file: for line in f: for x in range(548): out_file.write(f"{line.strip()}\n") f.close() out_file.close()
输出为重复的单列内容:
A A A A B B B ....
- 尝试添加第二列的代码:
with open(r'C:\Users\soso-\Desktop\SVM\DataSet\drug_list.txt') as f: with open(r'integrated_x.csv') as read_obj, \ open('integrated_x12.csv', 'w', newline='') as write_obj: # Create a csv.reader object from the input file object csv_reader = csv.reader(read_obj) # Create a csv.writer object from the output file object csv_writer = csv.writer(write_obj) # Read each row of the input csv file as list for row in csv_reader: for line in f: # Append the default text in the row / list row.append(line) # Add the updated row / list to the output file csv_writer.writerow(row)
得到错误输出:
A,"A" A,"A,B" A,"A,B,C"
错误原因分析
- 第一步硬编码
range(548)不灵活,且生成中间文件属于冗余操作,增加复杂度。 - 第二步核心问题:文件对象
f是一次性迭代器,第一次遍历后就会耗尽,后续循环无法读取新内容;同时直接append(line)未处理换行符,且循环逻辑错误,导致多行内容被拼接到同一行。
正确解决方案
方法1:使用itertools.product(推荐)
Python标准库的itertools.product可直接生成笛卡尔积,一步到位无需中间文件:
import csv from itertools import product # 读取原始文件内容,去除换行符和空行 with open(r'C:\Users\soso-\Desktop\SVM\DataSet\drug_list.txt', 'r') as f: items = [line.strip() for line in f if line.strip()] # 生成笛卡尔积并写入CSV with open('cartesian_product.csv', 'w', newline='') as out_file: writer = csv.writer(out_file) # product(items, items) 生成所有两两组合 writer.writerows(product(items, items))
方法2:手动嵌套循环实现
无需依赖itertools,用两层嵌套循环直接生成结果:
import csv # 读取原始数据 with open(r'C:\Users\soso-\Desktop\SVM\DataSet\drug_list.txt', 'r') as f: items = [line.strip() for line in f if line.strip()] # 写入CSV with open('cartesian_product.csv', 'w', newline='') as out_file: writer = csv.writer(out_file) for item1 in items: for item2 in items: writer.writerow([item1, item2])
修复原有代码(仅作参考)
如果要基于原有两步操作修改,需解决文件迭代器耗尽和循环逻辑问题:
import csv # 先读取原始列表并保存,避免迭代器耗尽 with open(r'C:\Users\soso-\Desktop\SVM\DataSet\drug_list.txt', 'r') as f: items = [line.strip() for line in f if line.strip()] # 生成第一列重复的文件,用len(items)代替硬编码的548 with open('integrated_x.csv', 'w') as out_file: for item in items: for _ in range(len(items)): out_file.write(f"{item}\n") # 合并两列 with open('integrated_x.csv', 'r') as read_obj, \ open('integrated_x12.csv', 'w', newline='') as write_obj: reader = csv.reader(read_obj) writer = csv.writer(write_obj) # 按第二列元素循环,每个元素对应第一列的一组重复项 for item2 in items: for _ in range(len(items)): row = next(reader) row.append(item2) writer.writerow(row)
内容的提问来源于stack exchange,提问作者Sara Almashharawi
相关产品推荐
相关产品推荐

