【问题标题】:Merging CSV files with a single column into one CSV file with 14 columns将单列的 CSV 文件合并为一个 14 列的 CSV 文件
【发布时间】:2014-09-12 12:41:19
【问题描述】:

我目前有 14 个 CSV 文件,每个文件包含一天的一列数据(14 个,因为它可以追溯到 2 周)

我想要做的是制作一个 CSV 文件,其中包含来自所有 14 个 CSV 的数据

例如。如果每个 CSV 都包含以下内容:

1
2
3
4

我希望结果是一个 csv 文件

1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,

(实际的 CSV 有 288 行)

我目前正在使用我在另一个问题中找到的一些代码,它适用于 2 或 3 个 CSV,但当我添加更多时,它并没有超过前 3 个,代码现在看起来非常混乱。

为大量代码道歉,但这是我目前所拥有的。

def csvappend():
    with open('C:\dev\OTQtxt\\result1.csv', 'rb') as csv1:
        with open('C:\dev\OTQtxt\\result2.csv', 'rb') as csv2:
            with open('C:\dev\OTQtxt\\result3.csv', 'rb') as csv3:
                with open('C:\dev\OTQtxt\\result4.csv', 'rb') as csv4:
                    with open('C:\dev\OTQtxt\\result5.csv', 'rb') as csv5:
                        with open('C:\dev\OTQtxt\\result6.csv', 'rb') as csv6:
                            with open('C:\dev\OTQtxt\\result7.csv', 'rb') as csv7:
                                with open('C:\dev\OTQtxt\\result8.csv', 'rb') as csv8:
                                    with open('C:\dev\OTQtxt\\result9.csv', 'rb') as csv9:
                                        with open('C:\dev\OTQtxt\\result10.csv', 'rb') as csv10:
                                            with open('C:\dev\OTQtxt\\result11.csv', 'rb') as csv11:
                                                with open('C:\dev\OTQtxt\\result12.csv', 'rb') as csv12:
                                                     with open('C:\dev\OTQtxt\\result13.csv', 'rb') as csv13:
                                                        with open('C:\dev\OTQtxt\\result14.csv', 'rb') as csv14:

                                                            reader1 = csv.reader(csv1, delimiter=',')
                                                             reader2 = csv.reader(csv2, delimiter=',')
                                                        reader3 = csv.reader(csv3, delimiter=',')
                                                        reader4 = csv.reader(csv4, delimiter=',')
                                                        reader5 = csv.reader(csv5, delimiter=',')
                                                        reader6 = csv.reader(csv6, delimiter=',')
                                                        reader7 = csv.reader(csv7, delimiter=',')
                                                        reader8 = csv.reader(csv8, delimiter=',')
                                                        reader9 = csv.reader(csv9, delimiter=',')
                                                        reader10 = csv.reader(csv10, delimiter=',')
                                                        reader11 = csv.reader(csv11, delimiter=',')
                                                        reader12 = csv.reader(csv12, delimiter=',')
                                                        reader13 = csv.reader(csv13, delimiter=',')
                                                        reader14 = csv.reader(csv14, delimiter=',')

                                                        all = []
                                                        for row1, row2, row3, row4, row5, row6, row7, row8, row9, \
                                                            row10, row11, row12, row13, row14 in zip(reader1, \
                                                                                                     reader2, reader3,\
                                                                                                     reader4, reader5, \
                                                                                                     reader7, reader8,\
                                                                                                     reader9, reader10, \
                                                                                                     reader11, reader12,\
                                                                                                     reader13,reader14):
                                                            row14.append(row1[0])
                                                            row14.append(row2[0])
                                                            row14.append(row3[0])
                                                            row14.append(row4[0])
                                                            row14.append(row5[0])
                                                            row14.append(row6[0])
                                                            row14.append(row7[0])
                                                            row14.append(row8[0])
                                                            row14.append(row9[0])
                                                            row14.append(row10[0])
                                                            row14.append(row11[0])
                                                            row14.append(row12[0])
                                                            row14.append(row13[0])
                                                            all.append(row14)

            with open('C:\dev\OTQtxt\TODAY.csv', 'wb') as output:
                writer = csv.writer(output, delimiter=',')
                writer.writerows(all)

我认为我的一些缩进在复制时搞砸了,但你应该明白这一点。而且我不希望通读所有这些内容,它非常重复。

我看到一些类似/相关的问题推荐unix 工具。如果有人建议我最好告诉你这将在 Windows 上运行。

如果有人对我如何清理它并真正让它工作有任何想法。我将不胜感激!

【问题讨论】:

  • docs.python.org/2/reference/… with 有一个变体:with A() as a, B() as b ..,这可以杀死那些缩进。并将所有 csv* 放入某种列表中并对其进行迭代
  • 好的,所以我可以使用 with 变体来清理内容。你介意举一个迭代的例子吗?在for csv in csv_list: 之后我不知道该怎么做

标签: python parsing csv


【解决方案1】:

创建文件:

xxxx@xxxx:/tmp/files$ for i in {1..15}; do echo -e "1\n2\n3\n4" > "my_csv_$i.csv"; done
xxxx@xxxx:/tmp/files$ more my_csv_1.csv 
1
2
3
4
xxxx@xxxx:/tmp/files$ ls
my_csv_10.csv  my_csv_11.csv  my_csv_12.csv  my_csv_13.csv  my_csv_14.csv  my_csv_15.csv  my_csv_1.csv  my_csv_2.csv  my_csv_3.csv  my_csv_4.csv  my_csv_5.csv  my_csv_6.csv  my_csv_7.csv  my_csv_8.csv  my_csv_9.csv

使用itertools.izip_longest

  with open('result.csv', 'w') as f_obj:
     rows = []
     files = os.listdir('.')
     for f in files:
      rows.append(open(f).readlines())
     iter = izip_longest(*rows)
     for row in iter:
      f_obj.write(','.join([field.strip() for field in row if field is not None])+'\n')

输出:

xxxxx@xxxx:/tmp/files$ more result.csv 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4

这不是最好的解决方案,因为您会将所有数据都放在内存中。但是你应该知道如何做到这一点。顺便说一句,如果你所有的数据都是数字,我会留在numpy 并使用多维数组。

【讨论】:

  • 文件(完成后)将自动生成,并以日期作为文件名。 (附加 .csv)无论 CSV 的名称是什么,这仍然有效吗?
  • 如你所见,我没有明确指定文件名
  • 这似乎是一个非常干净的解决方案!我会试一试,看看会发生什么!
  • 有点奇怪的结果。该脚本运行良好,速度非常快。但是,它会将自身读取为要附加的文件之一。所以我从脚本本身中获取代码行。
  • 这并不奇怪,但正是os.listdir('.') 所做的。你不应该使用它,因为你永远不知道还有哪些文件最终会出现在这个文件夹中。最好写一个生成文件名的函数。
【解决方案2】:

你可以用这个,文件名也可以循环指定:

import numpy as np

filenames = ['file1', 'file2', 'file3']  # all the files to be read in
data = []  # saves data from the files
for filename in filenames:
    data.append(open(filename, 'r').readlines())  # append a list of all numbers in the current file
data = np.matrix(data).T  # transpose the list of list using numpy

data_string = '\n'.join([','.join([k.strip() for k in j]) for j in data.tolist()])  # create a string by separating inner elements by ',' and outer list by '\n'

with open('newfile', 'w') as fp:
    fp.write(data_string)

【讨论】:

    【解决方案3】:

    刚刚测试过:

    import csv
    import glob
    
    files = glob.glob1("C:\\dev\\OTQtxt", "*csv")
    
    rows=[]
    
    with open('C:\\dev\\OTQtxt\\one.csv', 'a') as oneFile:
        for file in files:
            rows.append(open("C:\\dev\\OTQtxt\\" + file, 'r').read().splitlines())
        for row in rows:
            writer = csv.writer(oneFile)        
            writer.writerow(''.join(row))
    

    这将在您的目录中生成一个带有 csv 的文件 one.csv,其中将包含所有合并的 *csv 文件

    【讨论】:

    • 除了这不能提供所需的输出之外,使用files = *.csv in this folder 之类的东西也不好。如果您运行该脚本,然后更新单个 .csv 文件并再次运行该脚本会怎样? one.csv 将被包含并附加到其自身。如果下周也在这个文件夹中呢?您应该指定要解析的文件的名称,而不是只获取文件夹中的所有内容。
    猜你喜欢
    • 2018-03-30
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 2019-03-14
    相关资源
    最近更新 更多