繁体   English   中英

如果第一列匹配,则将行从一个 csv 附加到另一个

[英]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

file1file2都是无序的,并且具有相同数量的匹配行(~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_afile_b的长度不同,因此可以安全地假设它们在 A 列中可能具有不相交的类别数。也就是说,一个类别( bear / apple等)可能存在于一个文件中,而不是另一个。

出于这个原因,我使用的是defaultdict 这意味着,如果密钥不存在,它将自动创建并存储一个空列表。 如果我们以前见过那个键,我们只是针对它扩展现有列表。 如果我们还没有,我们以完全相同的方式对待它,但只是扩展存在的默认空列表。

您可以通过在file_afile_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM