如何合并 CSV 文件,以便将具有唯一标识符的行添加到输出的同一行中?

How to merge CSV files such that rows with a unique identifier are added into the same row of the output?

我正在使用 Python 将 4 个无头 CSV 合并到一个输出文件中。

每个 CSV 在第一列中都有一个唯一编号,如下面的 2 个示例 CSV 文件所示:

1.csv

1,Ringo,Beatles
2,John,Beatles
3,Mick,Rolling Stones
4,Keith,Rolling Stones
5,Rivers,Weezer

2.csv

1,TSLA,XNAS,1.0,USD
2,AAPL,XNAS,1.0,USD
3,SPY,ARCX,1.0,USD
4,BP LN,XLON,1.0,GBP
5,ESUD,XCME,1.0,USD

我使用以下代码生成了这些 CSV 的输出。

import os
import csv

filenames = ['1.csv', '2.csv', '3.csv', '4.csv']
with open('output_file', 'w') as outfile:
    for fname in filenames:
        with open(fname) as infile:
            outfile.write(infile.read())

这工作正常并输出一个文件。数据最终如下

1,Ringo,Beatles
2,John,Beatles
3,Mick,Rolling Stones
4,Keith,Rolling Stones
5,Rivers,Weezer
1,TSLA,XNAS,1.0,USD
2,AAPL,XNAS,1.0,USD
3,SPY,ARCX,1.0,USD
4,BP LN,XLON,1.0,GBP
5,ESUD,XCME,1.0,USD1,5,-600,1043.22,-625932.00
3,5,200,304.89,60978.00
5,4,6,3015.25,904575.005,4,-1,2,3009.50
5,4,1,1,3011.75
4,3,1,1000,308.37
4,3,1,200,309.15
1,3,1,100,309.0125

有没有一种方法可以将第一列编号用作 'unique' 编号 link 数据,这样它就可以获取以“1”开头的三个结果,并将它们添加到同一行?

例如,这些具有相同的 'unique' 数字 '1':

1,Ringo,Beatles
1,TSLA,XNAS,1.0,USD
1,3,1,100,309.0125

结果行将是:

(1) Ringo,Beatles,TSLA,XNAS,1.0,USD,3,1,100,309.0125

您可以使用字典将所有数据作为

{
1: [1, "Ringo", "Beatles", 1, "TSLA", "XNAS", 1.0, "USD", 1, 3, 1, 100, 309.0125], 
2: [2, ...],
3: [3, ...],
...
}

然后全部写入新文件。

所以首先创建空字典。 IE。 new_rows = {}

接下来从文件中获取行,获取 ID 并检查它是否存在于字典中。如果不存在,则使用只有 ID new_rows[key] = [key]

的列表创建它

接下来您可以将行中的其他值添加到此列表 new_rows[key] += values

对所有文件中的所有行重复此操作。

稍后您可以使用此字典将所有行写入新文件。


我用io只是模拟内存中的文件,你应该用open()

text1 = '''1,Ringo,Beatles
2,John,Beatles
3,Mick,Rolling Stones
4,Keith,Rolling Stones
5,Rivers,Weezer'''

text2 = '''1,TSLA,XNAS,1.0,USD
2,AAPL,XNAS,1.0,USD
3,SPY,ARCX,1.0,USD
4,BP LN,XLON,1.0,GBP
5,ESUD,XCME,1.0,USD'''

import os
import csv
import io

new_rows = {} # dict

filenames = [text1, text2]
#filenames = ['1.csv', '2.csv', '3.csv', '4.csv']

for fname in filenames:
    #with open(fname) as infile:
    with io.StringIO(fname) as infile:

        reader = csv.reader(infile)
        for row in reader:

            key = row[0]      # ID
            values = row[1:]  # rest
            
            # create key if not exists
            if key not in new_rows:
                new_rows[key] = [key]
                
            new_rows[key] += values  # add two lists
            
            # OR

            #if key not in new_rows:
            #    new_rows[key] = values    # only for first file
            #else:
            #     new_rows[key] += values  # for other file - add two lists 

# --- write it  ---

with open('output_file', 'w') as outfile:
    writer = csv.writer(outfile)
    all_rows = new_rows.values()
    writer.writerows(all_rows)   # `writerows` with `s` to write list with many rows.

顺便说一句:

在旧的 Python dict 中不必保持顺序,因此它可以以不同的顺序写入新行 - 它需要在保存之前对行列表进行排序,否则它需要使用 collections.OrderedDict()