【问题标题】:Python combine rows from different files into one data filePython 将不同文件中的行合并到一个数据文件中
【发布时间】:2016-03-19 21:32:15
【问题描述】:

我在多个大型 csv 文件中分发了信息。 我想将所有文件合并到一个新文件中,例如将第一个文件的第一行合并到另一个文件的第一行等。

file1.csv

A,B
A,C
A,D

file2.csv

F,G
H,I
J,K

预期结果:

output.csv

A,B,F,G
A,C,H,I
A,D,J,K

所以考虑我有一个数组['file1.csv', 'file2.csv', ...] 从这里怎么走?

我尝试将每个文件加载到内存中并通过np.column_stack 组合,但我的文件太大而无法放入内存。

【问题讨论】:

  • 我不会为您编写代码,但我建议逐行遍历文件并使用str.join(',',(file1line,file2line)) 构建您的输出行。您可能还必须从输入行中删除换行符。
  • @SiHa。感谢您的评论。但是我的问题是我有 50 个文件。如何并行遍历所有文件?
  • 50 个文件有点棘手 :) 请参阅下面的答案。

标签: python python-2.7 csv numpy file-io


【解决方案1】:

不是漂亮的代码,但这应该可以。

我没有使用with(open'filename','r') as myfile 作为输入。 50 个文件可能会有点混乱,所以这些文件是显式打开和关闭的。

它打开每个文件,然后将句柄放在一个列表中。第一个句柄作为主文件,然后我们逐行遍历它,每次从所有其他打开的文件中读取一行并将它们与',' 连接,然后将其输出到输出文件。

请注意,如果其他文件有更多行,则不会包含它们。如果有更少的行,这将引发异常。我会让你优雅地处理这些情况。

另请注意,如果名称遵循逻辑模式,您可以使用 glob 创建 filelist(感谢 N. Wouda,如下)

filelist = ['book1.csv','book2.csv','book3.csv','book4.csv']
openfiles = []
for filename in filelist:
    openfiles.append(open(filename,'rb'))

# Use first file in the list as the master
# All files must have same number of lines (or greater)
masterfile = openfiles.pop(0) 

with (open('output.csv','w')) as outputfile:
    for line in masterfile:
        outputlist = [line.strip()]
        for openfile in openfiles:
            outputlist.append(openfile.readline().strip())
        outputfile.write(str.join(',', outputlist)+'\n')

masterfile.close()
for openfile in openfiles:
    openfile.close()

输入文件

a   b   c   d   e   f
1   2   3   4   5   6
7   8   9   10  11  12
13  14  15  16  17  18

输出

a   b   c   d   e   f   a   b   c   d   e   f   a   b   c   d   e   f   a   b   c   d   e   f
1   2   3   4   5   6   1   2   3   4   5   6   1   2   3   4   5   6   1   2   3   4   5   6
7   8   9   10  11  12  7   8   9   10  11  12  7   8   9   10  11  12  7   8   9   10  11  12
13  14  15  16  17  18  13  14  15  16  17  18  13  14  15  16  17  18  13  14  15  16  17  18

【讨论】:

  • 请注意,如果文件列表中的所有文件共享逻辑结构(如file1.csvfile2.csv 等),您可以避免手动列出文件列表中的所有文件。只需这样做:from glob import glob,然后像这样获取文件filelist = glob('file*.csv')
  • @N.Wouda:谢谢,已将您的建议添加到答案中。
【解决方案2】:

您可以逐行遍历它们,而不是将文件完全读入内存。

from itertools import izip # like zip but gives us an iterator

with open('file1.csv') as f1, open('file2.csv') as f2, open('output.csv', 'w') as out:
    for f1line, f2line in izip(f1, f2):
        out.write('{},{}'.format(f1line.strip(), f2line))

演示:

$ cat file1.csv 
A,B
A,C
A,D
$ cat file2.csv 
F,G
H,I
J,K
$ python2.7 merge.py
$ cat output.csv 
A,B,F,G
A,C,H,I
A,D,J,K

【讨论】:

  • 为了完整起见,在 python 3 中,内置的 zip 也会生成一个迭代器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多