合并列顺序不同的CSV文件并去重

0 投票
3 回答
4154 浏览
提问于 2025-04-18 04:10

我有多个CSV文件,它们的列数是一样的,但每个文件里的列顺序却不一样。我想把这些文件合并在一起,并去掉重复的内容。这里的其他解决方案都没有考虑列的顺序,所以合并后的结果是错误的。那么,有什么办法可以在Windows命令行(比如logparser)或者bash中做到这一点呢?

另外,用Python脚本来实现这个功能也可以。

3 个回答

0

我个人建议把合并文件和去重这两个任务分开来做。如果可以的话,我还推荐使用数据库,而不是CSV文件,因为在数据库中管理列会更简单。

下面是一个使用Python的例子,Python有一个很容易使用的csv库。

import csv
with open(srcPath, 'r') as srcCSV:
    csvReader = csv.reader(csvFile, delimiter = ',')

    with open(destPath, 'rw') as destCSV:
        csvWriter = csv.writer(destCSV, delimiter = ',')        

        for record in csvReader:
            csvWriter.writerow(record[1],record[3],record[2], ... record[n])

这样你就可以按照自己想要的顺序重新排列列。目标CSV文件可以是一个已经存在的文件,你可以在上面扩展,或者是一个新的文件,格式更好。使用CSV库可以帮助你避免在其他地方可能出现的抄写错误。

一旦数据合并好了,你可以用同样的库来遍历这个合并后的数据文件,找出那些完全相同的记录。

注意:这种方法是逐行读取和写入文件的,所以可以处理任何大小的文件。我用这种方法合并了2.21亿条记录,文件大小最大达到6GB。

1

csvkit 这个工具可以做到这一点。

csvjoin -c "Column 1,Column 2" --outer file1.csv file2.csv
1

下面这个脚本在以下情况下可以正常工作:

  • CSV文件不要太大(也就是说,能够在内存中加载)
  • CSV的第一行要包含列名

你只需要填写 filesfinal_headers 这两个部分

import csv

files = ['c1.csv', 'c2.csv', 'c3.csv']
final_headers = ['col1', 'col2', 'col3']

merged_rows = set()
for f in files:
    with open(f, 'rb') as csv_in:
        csvreader = csv.reader(csv_in, delimiter=',')
    headers = dict((h, i) for i, h in enumerate(csvreader.next()))
        for row in csvreader:
            merged_rows.add(tuple(row[headers[x]] for x in final_headers))
with open('output.csv', 'wb') as csv_out:
    csvwriter = csv.writer(csv_out, delimiter=',')
    csvwriter.writerows(merged_rows)

撰写回答