【问题标题】:Writing columns from separate files into a single file将单独文件中的列写入单个文件
【发布时间】:2014-02-18 23:41:27
【问题描述】:

我对在 python 中处理 csv 文件比较陌生,希望得到一些指导。我有 6 个单独的 csv 文件。我想将每个 csv 文件中第 1 列、第 2 列和第 3 列的数据复制到新文件中相应的前 3 列中。

我如何在我的代码中写上它?

这是我不完整的代码:

import csv

file1 = open ('fileA.csv', 'rb')
reader1 = csv.reader (file1)
file2 = open ('fileB.csv', 'rb')
reader2 = csv.reader (file2)
file3 = open ('fileC.csv', 'rb')
reader3 = csv.reader (file3)
file4 = open ('fileD.csv', 'rb')
reader4 = csv.reader (file4)
file5 = open ('fileE.csv', 'rb')
reader5 = csv.reader (file5)
file6 = open ('fileF.csv', 'rb')
reader6 = csv.reader (file6)

WriteFile = open ('NewFile.csv','wb')
writer = csv.writer(WriteFile)

next(reader1, None)
Data1 = (col[0:3] for col in reader1)
next(reader2, None)
Data2 = (col[0:3] for col in reader2)
next(reader3, None)
Data3 = (col[0:3] for col in reader3)
next(reader4, None)
Data4 = (col[0:3] for col in reader4)
next(reader5, None)
Data5 = (col[0:3] for col in reader5)
next(reader6, None)
Data6 = (col[0:3] for col in reader6)
.......????????

file1.close()
file2.close()
file3.close()
file4.close()
file5.close()
file6.close()
WriteFile.close()

谢谢!

【问题讨论】:

  • 你能给我们展示一些小的示例输入和预期的输出吗?你想要文件 1 中每一行的前 3 列,然后是文件 2 中每一行的前 3 列,等等?或者交错,所以文件 1 中第一行的前 3 列,然后是文件 2 中第一行的前 3 列,...,文件 6,然后是文件 1 中的第二行,等等?还是以某种方式“合并”?还是……?

标签: python csv merge


【解决方案1】:

如果您只想将这些全部连接起来,那很容易。您可以在每个迭代器上调用 writerows,或者将它们一起调用 chain

writer.writerows(itertools.chain(Data1, Data2, Data3, Data4, Data5, Data6))

或者,如果您希望它们交错,从 Data1 中获取第 1 行,然后从 Data 2 中获取第 1 行,依此类推,然后从 Data 1 中获取第 2 行,依此类推,使用 zip 转置数据,然后再次chain 将其展平:

writer.writerows(itertools.chain.from_iterable(zip(Data1, Data2, Data3, 
                                                   Data4, Data5, Data6)))

如果文件的长度不同,zip 将在您到达任何个文件的末尾时立即停止。那是你要的吗?我不知道。你可能想要那个。您可能想用空白行填充空白(在这种情况下,请查看zip_longest)。您可能想跳过这些空白(您可以使用zip_longest 加上filter 来完成)。或一百万种其他可能性。


附带说明一下,一旦您获得了这么多相似的变量,这通常表明您确实想要一个可迭代的而不是单独的变量。例如:

filenames = ('fileA.csv', 'fileB.csv', 'fileC.csv', 
             'fileD.csv', 'fileE.csv', 'fileF.csv')
files = [open(filename, 'rb') for filename in filenames]
readers = [csv.reader(file) for file in files]

WriteFile = open ('NewFile.csv','wb')
writer = csv.writer(WriteFile)

for reader in readers:
    next(reader, None)

Data = [(col[0:3] for col in reader) for reader in readers]

writer.writerows(itertools.chain.from_iterable(Data))

for file in files:
    file.close()
WriteFile.close()

(请注意,对于文件、读取器、数据等的集合,我使用了列表推导,而不是生成器表达式。那是因为我们需要反复迭代它们——例如,为每个文件创建一个 reader,然后在每个文件上调用close。另外,因为有固定的少量元素——6——所以“浪费”整个列表并不是什么问题。)

【讨论】:

  • 非常感谢您的解释。我喜欢 itertools 方法。使用 itertools 方法,我收到以下错误: Traceback(最近一次调用最后一次):文件“C:\Python33\Joining_columns_csv.py”,第 12 行,在 next(reader, None) _csv.Error: iterator should返回字符串,而不是字节(您是否以文本模式打开文件?)您能帮我解决这个错误吗?
  • 嗯,该错误消息来自原始代码中的next 调用,甚至在它使用chain 调用到达writerows 之前。很明显,您发布的代码甚至在达到这一点之前就已经被破坏了,或者您的实际代码与您发布的代码不同。无论哪种方式,都没有办法解决这个问题。也许问一个新问题,发布一个 MCVE 来证明它?
  • @user3302763:但我可以快速猜测一下:如果您使用的是 Python 2,您总是希望提供 csv 模块二进制文件,但在 Python 3 中,您通常希望提供它文本文件。我的猜测是您输入了一些适用于 2.x 的示例代码并尝试在 3.3 中运行它。请参阅 3.x 文档中的示例,例如 this one,而不是:open 'r' 模式下的文件,而不是 'rb' 模式。
  • 谢谢。是的,我最近升级到了 python 3,它让我对 python 2 的所有小变化感到悲痛。我将读取和模式从“rb”更改为“rt”,它解决了这个问题。再次感谢。非常感谢!
【解决方案2】:

我理解您的问题的方式是您有六个单独的 csv,每个 csv 有 3 列,并且每列中的数据在所有六个文件中都是相同的类型。如果是这样,您可以使用熊猫。假设您有 3 个文件看起来像...

file1:
      col1    col2   col3
        1       1      1
        1       1      1

然后是第二个和第三个文件,第二个是 2,第三个是 3,你可以写...

#!/usr/bin/env python

import pandas as pd

cols = ['col1', 'col2', 'col3']
files = ['~/one.txt', '~/two.txt', '~/three.txt']
data_1 = pd.read_csv(files[0], sep=',', header=False, names=cols)
data_2 = pd.read_csv(files[1], sep=',', header=False, names=cols)
data_3 = pd.read_csv(files[2], sep=',', header=False, names=cols)

data_final = data_1.append(data_2).append(data_3)

那么 data_final 应该将所有三个数据集的内容相互堆叠。您可以修改 6 个(或 n 个)数据集。希望这是你想要的。

Out[1]:    col1    col2    col3
             1       1       1
             1       1       1
             2       2       2
             2       2       2
             3       3       3
             3       3       3

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 2012-07-24
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    相关资源
    最近更新 更多