根据模板标题在Python中合并多个CSV文件

1 投票
1 回答
1284 浏览
提问于 2025-04-18 16:42

我有多个csv文件,它们的表头大致相同。有些文件可能有所有的表头,有些则可能缺少一些。我想用一个公共的csv文件,这个文件只包含表头,然后把所有的文件合并在一起。

示例表头:

a, b, c, d, e, f,

文件1:

a, b, d,
1, 2, 3,

文件2:

a, b, c, e,
4, 5, 6, 7,

合并结果:

a, b, c, d, e, f,
1, 2,  , 3,
4, 5, 6,  , 7,  ,

到目前为止,有人建议我使用csv.DictReader和csv.DictWriter。不过,我在根据公共表头合并文件时遇到了麻烦,还想保持表头的顺序。有没有办法让我继续使用这些工具,而不对表头进行排序呢?

我试过pandas的合并功能,但它需要一个排序的依据,而我的数据中没有这个。

任何帮助都非常感谢。谢谢!

1 个回答

1

所以我决定帮你创建一个类来实现这个功能。它会返回一个生成器,你可以通过它来逐步构建你的最终文件。

import csv
class DataFile(object):
    empty = ''  # use this if col does not have value

    def __init__(self, filename):
        f = open(filename, 'r')
        self.reader = csv.reader(f)
        # set first line as header
        self.header = [x.strip() for x in self.reader.next()]

    def get_header(self):
        return self.header

    def with_header(self, headers):
        """ Returns a generator for specified headers"""
        header_dict = dict([(a, i,) for i, a in enumerate(self.header)])

        for line in self.reader:
            li = []
            for h in headers:
                if h in header_dict:
                    li.append(line[header_dict[h]])
                else:
                    li.append(self.empty)
            yield li

你可以用它来合并文件,比如 file1.csvfile2.csv,方法如下:

>>> one = DataFile('file1.csv')
>>> two = DataFile('file2.csv')
>>> one.get_header()
['a', 'b', 'd', '']
>>> comb = set(one.get_header() + two.get_header())
>>> final = list(one.with_header(comb)) + list(two.with_header(comb))
>>> final
[['1', '', '', ' 2', '', ' 3'], ['4', '', ' 6', ' 5', ' 7', '']]

然后你可以使用 combfinal 来生成你新的 csv 文件(可以用 csv 写入器等等)。另外,你还可以创建一个函数,接受多个文件,然后返回一个新的生成器,里面包含所有文件的所有列等等。当某个值在文件中不存在时,可以通过修改 empty 属性来改变设置的字符。我觉得这个过程很简单易懂。

撰写回答