使用不同的列在Python中合并CSV

Ale*_*ont 11 python csv merge

我有数百个大型CSV文件,我想合并为一个.但是,并非所有CSV文件都包含所有列.因此,我需要根据列名而不是列位置合并文件.

需要明确的是:在合并的CSV中,对于来自没有该单元格列的行的单元格,值应为空.

我不能使用pandas模块,因为它让我的内存耗尽.

有没有可以做到这一点的模块,或者一些简单的代码?

Aar*_*key 15

csv.DictReadercsv.DictWriter类应该很好地工作(见Python文档).像这样的东西:

import csv
inputs = ["in1.csv", "in2.csv"]  # etc

# First determine the field names from the top line of each input file
# Comment 1 below
fieldnames = []
for filename in inputs:
  with open(filename, "r", newline="") as f_in:
    reader = csv.reader(f_in)
    headers = next(reader)
    for h in headers:
      if h not in fieldnames:
        fieldnames.append(h)

# Then copy the data
with open("out.csv", "w", newline="") as f_out:   # Comment 2 below
  writer = csv.DictWriter(f_out, fieldnames=fieldnames)
  for filename in inputs:
    with open(filename, "r", newline="") as f_in:
      reader = csv.DictReader(f_in)  # Uses the field names in this file
      for line in reader:
        # Comment 3 below
        writer.writerow(line)
Run Code Online (Sandbox Code Playgroud)

上述评论:

  1. 您需要提前指定所有可能的字段名称DictWriter,因此您需要遍历所有CSV文件两次:一次查找所有标题,一次读取数据.没有更好的解决方案,因为在DictWriter编写第一行之前需要知道所有头文件.使用集合而不是列表(列表中的in运算符相对较慢),这部分会更有效,但对于几百个标题,它不会有太大的区别.集合也会丢失列表的确定性排序 - 每次运行代码时,列都会以不同的顺序出现.
  2. 上面的代码适用于Python 3,在没有的情况下,CSV模块会发生奇怪的事情newline="".为Python 2删除它.
  3. 此时,line是一个dict,字段名称为键,列数据为值.您可以在DictReaderDictWriter构造函数中指定如何处理空值或未知值.

此方法不应耗尽内存,因为它永远不会立即加载整个文件.