合并列顺序不同的CSV文件并去重
我有多个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的第一行要包含列名
你只需要填写 files
和 final_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)