【问题标题】:How can I append columns from csv files to one file? [duplicate]如何将 csv 文件中的列附加到一个文件中? [复制]
【发布时间】:2019-03-28 01:59:31
【问题描述】:

我正在用 Python 编写脚本。我有一堆 csv 文件,每个文件包含 1 列。这些文件可能看起来像这样:

FirstFile.csv

First
a
b
c

SecondFile.csv

Second
a2
b2
c2

我想要创建一些结果文件(我们称之为 result.csv),如下所示:

First    Second
a        a2
b        b2
c        c2

如何在 python 的目录中附加所有 csv 并附加所有列,这样我就有了一个看起来像这样的 result.csv(当然,还有更多列)?

【问题讨论】:

  • 你以前用过熊猫吗?
  • 你有没有尝试过?
  • 如果您没有大小问题(例如每个文件数百万行或每列非常大的值)......只需加载所有文件并将它们写入一个新文件。查看模块csv 以便于编写。或者使用熊猫。
  • @mad_ 如果可以使用 csv 模块和单独列表同样快地完成此操作,则没有理由默认回到 pandas
  • @roganjosh 你是怪物吗?为什么你不喜欢熊猫。他们很可爱!

标签: python python-3.x csv scripting


【解决方案1】:

如果您正在寻找纯 Python 解决方案,最好使用 csv.DictReadercsv.DictWriter,这样您就可以更好地控制数据的格式。此外,所有内容都是动态“生成”的,因此对于非常大的文件,它的内存效率会更高。

import csv

with open('csv1.csv') as csv1, open('csv2.csv') as csv2:
    r1 = csv.DictReader(csv1)
    r2 = csv.DictReader(csv2)
    with open('csv3.csv', 'w') as csv3:
        writer = csv.DictWriter(csv3, 
            fieldnames=["First", "Second"],
            lineterminator='\n'
        )
        writer.writeheader()
        writer.writerows({**x, **y} for x, y in zip(r1, r2))

【讨论】:

    【解决方案2】:

    我确信还有更多的 Python 方法,但这会起作用(只要所有文件的行数相同)。

    input_files = ['FirstFile.csv', 'SecondFile.csv']
    csv_separator = '\t'
    
    data = []
    
    for file in input_files:
        partial_data = []
        with open(file, 'r') as f:
            for line in f:
                partial_data.append(line.strip('\n'))
            data.append(partial_data)
    
    with open('output.csv','w') as output:
        for item in range(len(data[0])):
            line = []
            for part in range(len(data)):
                line.append(data[part][item])
            output.write(csv_separator.join(line)+'\n')
    

    【讨论】:

      【解决方案3】:

      您可以使用 csv 模块:

      创建 10 个文件:

      filenames = []
      for i in range(10):
          filenames.append(f"file_{i}.txt")
          with open(filenames[-1],"w") as f:
              f.write(f"Header{i}\n")
              for row in range(5):
                  f.write(f"text_{i}_{row}\n")
      

      读入所有文件:

      data = []
      for f in filenames:       # filled when creating files, you can use os.walk to fill yours
          with open(f) as r:
              data.append([x.strip() for x in r])
      
      # data is a list of columns, we need a list of list of columns, so we transpose the data:
      transpose = zip(*data)
      
      # write the joined file
      import csv
      with open("joined.txt","w", newline="") as j:
          w = csv.writer(j)
          w.writerows(transpose)
      

      检查是否正常:

      with open("joined.txt") as j:
          print(j.read())
      

      输出:

      Header0,Header1,Header2,Header3,Header4,Header5,Header6,Header7,Header8,Header9
      text_0_0,text_1_0,text_2_0,text_3_0,text_4_0,text_5_0,text_6_0,text_7_0,text_8_0,text_9_0
      text_0_1,text_1_1,text_2_1,text_3_1,text_4_1,text_5_1,text_6_1,text_7_1,text_8_1,text_9_1
      text_0_2,text_1_2,text_2_2,text_3_2,text_4_2,text_5_2,text_6_2,text_7_2,text_8_2,text_9_2
      text_0_3,text_1_3,text_2_3,text_3_3,text_4_3,text_5_3,text_6_3,text_7_3,text_8_3,text_9_3
      text_0_4,text_1_4,text_2_4,text_3_4,text_4_4,text_5_4,text_6_4,text_7_4,text_8_4,text_9_4
      

      data 看起来像这样:

      [['Header0', 'text_0_0', 'text_0_1', 'text_0_2', 'text_0_3', 'text_0_4'], # one files data
       ['Header1', 'text_1_0', 'text_1_1', 'text_1_2', 'text_1_3', 'text_1_4'], 
       ['Header2', 'text_2_0', 'text_2_1', 'text_2_2', 'text_2_3', 'text_2_4'], 
       ['Header3', 'text_3_0', 'text_3_1', 'text_3_2', 'text_3_3', 'text_3_4'], 
       ['Header4', 'text_4_0', 'text_4_1', 'text_4_2', 'text_4_3', 'text_4_4'], 
       ['Header5', 'text_5_0', 'text_5_1', 'text_5_2', 'text_5_3', 'text_5_4'], 
       ['Header6', 'text_6_0', 'text_6_1', 'text_6_2', 'text_6_3', 'text_6_4'], 
       ['Header7', 'text_7_0', 'text_7_1', 'text_7_2', 'text_7_3', 'text_7_4'], 
       ['Header8', 'text_8_0', 'text_8_1', 'text_8_2', 'text_8_3', 'text_8_4'], 
       ['Header9', 'text_9_0', 'text_9_1', 'text_9_2', 'text_9_3', 'text_9_4']]
      

      转置后的样子:

      [('Header0', 'Header1', 'Header2', 'Header3', 'Header4', 'Header5', 'Header6', 'Header7', 'Header8', 'Header9'), 
       ('text_0_0', 'text_1_0', 'text_2_0', 'text_3_0', 'text_4_0', 'text_5_0', 'text_6_0', 'text_7_0', 'text_8_0', 'text_9_0'), 
       ('text_0_1', 'text_1_1', 'text_2_1', 'text_3_1', 'text_4_1', 'text_5_1', 'text_6_1', 'text_7_1', 'text_8_1', 'text_9_1'), 
       ('text_0_2', 'text_1_2', 'text_2_2', 'text_3_2', 'text_4_2', 'text_5_2', 'text_6_2', 'text_7_2', 'text_8_2', 'text_9_2'), 
       ('text_0_3', 'text_1_3', 'text_2_3', 'text_3_3', 'text_4_3', 'text_5_3', 'text_6_3', 'text_7_3', 'text_8_3', 'text_9_3'), 
       ('text_0_4', 'text_1_4', 'text_2_4', 'text_3_4', 'text_4_4', 'text_5_4', 'text_6_4', 'text_7_4', 'text_8_4', 'text_9_4')]
      

      【讨论】:

      • 我正在使用 csv 执行此操作,但转置 (transpose = zip(*data)) 似乎不起作用。
      • @yalpsideman 它适用于我发布的代码。 zip() 产生一个只能使用一次的生成器 - 如果你先打印它,然后再打印它,当你想写文件时。使用transpose = list( zip(*data)) 从转置后的值创建一个列表,以便您可以多次使用它们进行打印和文件写入
      【解决方案4】:

      您可以尝试使用 Pandas。

      import pandas as pd
      result = pd.concat([ pd.read_csv(f) for f in filenames ],axis=1)
      result.to_csv("result.csv",index=False)
      
      1. 创建文件名列表(例如filenames
      2. 导入熊猫
      3. 将 concat 函数与列表理解结合使用

      【讨论】:

        猜你喜欢
        • 2022-01-04
        • 1970-01-01
        • 1970-01-01
        • 2014-05-13
        • 2019-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-29
        相关资源
        最近更新 更多