[英]Appending rows from one csv to another if their first column matches
我有两个具有相同行但不同列的 csv 文件:
$ cat file1
category,a,b,c,d,e
apple,0,0,0,0,0
bear,1,1,1,1,1
$ cat file2
category,f,g,h,i,j
bear,10,10,10,10,10
apple,5,5,5,5,5
预期输出:
category,a,b,c,d,e,f,g,h,i,j
apple,0,0,0,0,0,5,5,5,5,5
bear,1,1,1,1,1,10,10,10,10,10
file1
和file2
都是无序的,并且具有相同数量的匹配行(~15000 行)。 file1
有 ~1000 列, file2
有 ~16000 列。 我使用了以下方法:
import csv
with open ("file1.csv") as f:
first = {rows[0]:rows[1:] for rows in list(csv.reader(f))}
with open("file2.csv") as f:
for row in csv.reader(f):
if row[0] in first:
first[row[0]].extend(row[1:])
# print(first)
# {'category': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], 'apple': ['0', '0', '0', '0', '0', '5', '5', '5', '5', '5'], 'bear': ['1', '1', '1', '1', '1', '10', '10','10', '10', '10']}
我觉得我越来越接近了,但我似乎无法first
使用与上述预期输出相同的格式进行编写。
附带说明一下,对文件进行排序然后附加是否有意义? 它们具有完全相同的行数和类别数。
你很接近,但有(IIUC)一些复杂的因素。 主要是file_a
和file_b
的长度不同,因此可以安全地假设它们在 A 列中可能具有不相交的类别数。也就是说,一个类别( bear
/ apple
等)可能存在于一个文件中,而不是另一个。
出于这个原因,我使用的是defaultdict
。 这意味着,如果密钥不存在,它将自动创建并存储一个空列表。 如果我们以前见过那个键,我们只是针对它扩展现有列表。 如果我们还没有,我们以完全相同的方式对待它,但只是扩展存在的默认空列表。
您可以通过在file_a
或file_b
放置一个全新的行来测试这file_b
; 代码将正常运行。
此外,通过封装在函数( build_output
)中,我们只需要with open()...
代码一次。 如果你想添加另一个文件,只需output = build_output('file_c.csv', output)
就会以同样的方式添加。
最后,我们将第一列用作字典中的键,并将文件中的所有其余值用作“值”。 我们需要将这些重新连接在一起作为一个列表。 我们可以使用第一列作为键,然后根据该键存储整行,但是如果键不出现多次,将很难将其写回。 相反,将key
括在一个列表中,并将其与值列表连接起来,以提供一个我们可以在一行上写入的列表。
import csv
from collections import defaultdict
output = defaultdict(list)
def build_output(file_name, output_obj):
with open(file_name) as infile:
reader_obj = csv.reader(infile)
for row in reader_obj:
output_obj[row[0]].extend(row[1:])
return output_obj
def write_output(output):
with open('output.csv', 'w', newline='') as outfile:
writer = csv.writer(outfile)
for key, value in output.items():
row = [key] + value
writer.writerow(row)
output = build_output('file_a.csv', output)
output = build_output('file_b.csv', output)
write_output(output)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.