【问题标题】:Merge multiple csv file based on a template header in python基于python中的模板头合并多个csv文件
【发布时间】:2014-10-03 04:33:57
【问题描述】:

我有多个 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 合并功能,但它需要一个排序依据,我的数据不包含。

感谢任何帮助。 谢谢

【问题讨论】:

  • 为什么不直接使用strip(',')split(', ') 解析输入,然后使用迭代器将write() 指向文件?
  • @Matt 这不是我的实际数据,我用它只是为了了解我正在处理的数据类型。这只是一个例子。我的标题类似于“010 C03AA01”,csv 文件中的数据可以是任何类型的字符串。有些 csv 文件可能有一行数据,有些可能有多个...
  • @cyrusR 你看过 csvkit:csvkit.readthedocs.org/en/0.8.0
  • 刚刚添加了一个可以用来解决问题的简单类

标签: python csv merge header


【解决方案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 属性来修改正在设置的字符。我认为这很容易理解

【讨论】:

  • 谢谢 tr33hous ;) 我把这个集合改成了一个列表,因为这个集合正在为我排序头文件...
猜你喜欢
  • 2021-09-27
  • 2019-07-13
  • 1970-01-01
  • 2020-07-23
  • 2019-05-07
  • 2018-06-11
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
相关资源
最近更新 更多