我有多个 CSV;但是,我很难合并它们,因为它们都有相同的 header 。这是一个例子。
CSV 1:
ID,COUNT
1,3037
2,394
3,141
5,352
7,31
CSV 2:
ID, COUNT
1,375
2,1178
3,1238
5,2907
6,231
7,2469
CSV 3:
ID, COUNT
1,675
2,7178
3,8238
6,431
7,6469
我需要合并 ID 上的所有 CSV 文件,并为每个计数列创建一个包含附加列的新 CSV。
我已经用 2 个 CSV 对其进行了测试,但仍然没有得到正确的输出。
with open('csv1.csv', 'r') as checkfile: #CSV Data is pulled from
checkfile_result = {record['ID']: record for record in csv.DictReader(checkfile)}
with open('csv2.csv', 'r') as infile:
#infile_result = {addCount['COUNT']: addCount for addCount in csv.Dictreader(infile)}
with open('Result.csv', 'w') as outfile:
reader = csv.DictReader(infile)
writer = csv.DictWriter(outfile, reader.fieldnames + ['COUNT'])
writer.writeheader()
for item in reader:
record = checkfile_result.get(item['ID'], None)
if record:
item['ID'] = record['COUNT'] # ???
item['COUNT'] = record['COUNT']
else:
item['COUNT'] = None
item['COUNT'] = None
writer.writerow(item)
但是,使用上面的代码,我得到三列,但第一个 CSV 中的数据填充在两列中。例如。
Result.CSV *注意键跳过了 CSV 中不存在的 ID
ID, COUNT, COUNT
1, 3037, 3037
2, 394, 394
3,141, 141
5,352. 352
7,31, 31
结果应该是:
ID, COUNT, COUNT
1,3037, 375
2,394, 1178
3,141, 1238
5,352, 2907
6, ,231
7,31, 2469
等等等等
任何帮助将不胜感激。
最佳答案
这有效:
import csv
def read_csv(fobj):
reader = csv.DictReader(fobj, delimiter=',')
return {line['ID']: line['COUNT'] for line in reader}
with open('csv1.csv') as csv1, open('csv2.csv') as csv2, \
open('csv3.csv') as csv3, open('out.csv', 'w') as out:
data = [read_csv(fobj) for fobj in [csv1, csv2, csv3]]
all_keys = sorted(set(data[0]).union(data[1]).union(data[2]))
out.write('ID COUNT COUNT COUNT\n')
for key in all_keys:
counts = (entry.get(key, '') for entry in data)
out.write('{}, {}, {}, {}\n'.format(key, *tuple(counts)))
输出文件的内容:
ID, COUNT, COUNT, COUNT
1, 3037, 375, 675
2, 394, 1178, 7178
3, 141, 1238, 8238
5, 352, 2907,
6, , 231, 431
7, 31, 2469, 6469
详细信息
函数read_csv
返回一个字典,其中 ids 作为键,count 作为值。我们将使用此函数读取所有三个输入。例如对于 csv1.csv
with open('csv1.csv') as csv1:
print(read_csv(csv1))
我们得到这个结果:
{'1': '3037', '3': '141', '2': '394', '5': '352', '7': '31'}
我们需要拥有所有 key 。一种方法是将它们转换为集合并使用 Union 来查找唯一的集合。我们还对它们进行排序:
all_keys = sorted(set(data[0]).union(data[1]).union(data[2]))
['1', '2', '3', '5', '6', '7']
在所有键的循环中,我们使用 entry.get(key, '')
检索计数。如果不包含该键,我们会得到一个空字符串。查看输出文件。您只看到逗号,并且在输入中未找到值的地方没有值。我们使用生成器表达式,因此不必将所有内容重新输入三次:
counts = (entry.get(key, '') for entry in data)
这是其中一个生成器的内容:
list(counts)
('3037', '375', '675')
最后,我们写入输出文件。 *
将像这样的元组 ('3037', '375', '675') 转换为三个参数,即 .format()
的调用方式如下 .format(key, '3037', '375', '675')
:
out.write('{}, {}, {}, {}\n'.format(key, *tuple(counts)))
关于csv - 在Python中合并三个具有相同标题的csv文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16149913/