我是Python的初学者。我有多个CSV文件(超过10个),并且它们都具有相同数量的列。我想将它们合并到一个CSV文件中,我不会重复标题。
所以基本上我需要只有第一行包含所有标题,然后我需要合并所有CSV文件中的所有行。我该怎么做?
感谢任何帮助。
谢谢!
答案 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)
您的尝试几乎奏效,但问题是:
这是已更正的代码,将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模块(或熊猫)也可以很好地处理这些情况。