![](/img/trans.png)
[英]Python: appending/merging multiple csv files respecting headers and write to csv
[英]Merging multiple CSV files without headers being repeated (using Python)
我是Python的初學者。 我有多個CSV文件(超過10個),並且它們都具有相同數量的列。 我想將它們合並到一個CSV文件中,我不會重復標題。
所以基本上我需要只有第一行包含所有標題,然后我需要合並所有CSV文件中的所有行。 我該怎么做呢?
這是我到目前為止所嘗試的內容。
import glob
import csv
with open('output.csv','wb') as fout:
wout = csv.writer(fout,delimiter=',')
interesting_files = glob.glob("*.csv")
for filename in interesting_files:
print 'Processing',filename
# Open and process file
h = True
with open(filename,'rb') as fin:
fin.next()#skip header
for line in csv.reader(fin,delimiter=','):
wout.writerow(line)
如果您使用的是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
雖然我認為最好的答案是來自@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)
如果您不介意開銷,可以使用隨附常見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時,它將數據表與標題分開,標題保存為數據dataframe
元dataframe
,即pandas中的標准數據類型。 如果你連接其中幾個dataframes
它只會連接dataframes
,如果它們的標題是相同的。 如果標題不相同則失敗並給出錯誤。 如果您的目錄被來自其他來源的CSV文件污染,可能是件好事。
另一件事:我剛剛在interesting_files
周圍添加了sorted()
。 我假設您的文件按順序命名,並且應該保留此順序。 我不確定glob,但os
函數不一定返回按名稱排序的文件。
你的縮進是錯誤的,你需要將循環放在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)
您的嘗試幾乎正常,但問題是:
這是更正后的代碼,將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模塊(或者pandas)也可以優雅地處理這些情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.