合并多个CSV文件而不重复标题(使用Python)

时间:2015-05-19 20:25:10

标签: python csv

我是Python的初学者。我有多个CSV文件(超过10个),并且它们都具有相同数量的列。我想将它们合并到一个CSV文件中,我不会重复标题。

所以基本上我需要只有第一行包含所有标题,然后我需要合并所有CSV文件中的所有行。我该怎么做?

感谢任何帮助。

谢谢!

5 个答案:

答案 0 :(得分:28)

如果您使用的是Linux系统:

head -1 director/one_file.csv > output csv   ## writing the header to the final file
tail -n +2  director/*.csv >> output.csv  ## writing the content of all csv starting with second line into final file

答案 1 :(得分:20)

虽然我认为最好的答案是来自@valentin的答案,但您可以在不使用csv模块的情况下完成此操作:

import glob

interesting_files = glob.glob("*.csv") 

header_saved = False
with open('output.csv','wb') as fout:
    for filename in interesting_files:
        with open(filename) as fin:
            header = next(fin)
            if not header_saved:
                fout.write(header)
                header_saved = True
            for line in fin:
                fout.write(line)

答案 2 :(得分:7)

如果您不介意开销,可以使用附带常见python发行版的pandas。如果你打算用speadsheet表做更多的事情,我推荐使用pandas,而不是试图编写你自己的库。

import pandas as pd
import glob
interesting_files = glob.glob("*.csv")
df_list = []
for filename in sorted(interesting_files):
    df_list.append(pd.read_csv(filename))
full_df = pd.concat(df_list)

full_df.to_csv('output.csv')

关于熊猫的更多信息。因为它是为了处理像数据这样的电子表格,所以它知道第一行是标题。在读取CSV时,它将数据表与标题分开,标题保留为pandas中标准数据类型dataframe的元数据。如果你连接其中几个dataframes,它只会连接数据集,如果它们的标题是相同的。如果标题不相同则失败并给出错误。如果您的目录被来自其他来源的CSV文件污染,可能是件好事。

另一件事:我刚刚在sorted()周围添加了interesting_files。我假设您的文件按顺序命名,并且应该保留此顺序。我不确定glob,但os函数不一定返回按名称排序的文件。

答案 3 :(得分:1)

您的缩进是错误的,您需要将循环放在with块中。您也可以将文件对象传递给writer.writerows。

import csv
with open('output.csv','wb') as fout:
    wout = csv.writer(fout)
    interesting_files = glob.glob("*.csv")
    for filename in interesting_files:
        print 'Processing',filename
        with open(filename,'rb') as fin:
                next(fin) # skip header
                wout.writerows(fin)

答案 4 :(得分:0)

您的尝试几乎奏效,但问题是:

  • 您正在打开文件以进行读取,但在写入行之前将其关闭。
  • 您永远不会写标题。你必须写一次
  • 此外,您还必须从“全局”中排除 output.csv,否则输出也将在输入中!

这是已更正的代码,将csv对象直接传递给csv.writerows方法以获取更短和更快的代码。还将标题从第一个文件写入输出文件。

import glob
import csv

output_file = 'output.csv'
header_written = False

with open(output_file,'w',newline="") as fout:  # just "wb" in python 2
    wout = csv.writer(fout,delimiter=',')
    # filter out output
    interesting_files = [x for x in glob.glob("*.csv") if x != output_file]
    for filename in interesting_files:
        print('Processing {}'.format(filename))
        with open(filename) as fin:
            cr = csv.reader(fin,delmiter=",")
            header = cr.next() #skip header
            if not header_written:
                wout.writerow(header)
                header_written = True
            wout.writerows(cr)

请注意,使用原始逐行处理的解决方案缺少一个要点:如果标头为多行,它们将惨遭失败,使标题行/标题行重复几次,从而有效地破坏了文件。

csv模块(或熊猫)也可以很好地处理这些情况。