2017-06-27 10 views
4

私は現在、以下のコードを使用して6,000のcsvファイル(ヘッダ付き)をインポートし、それらを単一のcsvファイル(ヘッダ行1個)にエクスポートします。複数のcsvファイルを同じヘッダで単一のcsvに連結する -

#import csv files from folder 
path =r'data/US/market/merged_data' 
allFiles = glob.glob(path + "/*.csv") 
stockstats_data = pd.DataFrame() 
list_ = [] 

for file_ in allFiles: 
    df = pd.read_csv(file_,index_col=None,) 
    list_.append(df) 
    stockstats_data = pd.concat(list_) 
    print(file_ + " has been imported.") 

このコードは正常に動作しますが、遅いです。処理には最大2日間かかります。

同じ(ただし、ヘッダーがない)Terminalコマンドラインのための1行のスクリプトが与えられました。このスクリプトは20秒かかります。

for f in *.csv; do cat "`pwd`/$f" | tail -n +2 >> merged.csv; done 

どのように私は最初のPythonスクリプトをスピードアップできるか知っていますか?時間を短縮するために、私はそれをDataFrameにインポートせずにCSVを連結することを考えましたが、わかりません。

ありがとうございました。

答えて

4

あなただけの入力から出力へコピーし、メモリにCSVを必要としない場合は、すべてで構文解析を回避するために、たくさん安くなる、とメモリに構築せずにコピーします:

import shutil 

#import csv files from folder 
path = r'data/US/market/merged_data' 
allFiles = glob.glob(path + "/*.csv") 
with open('someoutputfile.csv', 'wb') as outfile: 
    for i, fname in enumerate(allFiles): 
     with open(fname, 'rb') as infile: 
      if i != 0: 
       infile.readline() # Throw away header on all but first file 
      # Block copy rest of file from input to output without parsing 
      shutil.copyfileobj(infile, outfile) 
      print(fname + " has been imported.") 

これはそれです。 shutil.copyfileobjは効率的にデータをコピーし、Pythonレベルの作業を劇的に減らして解析し再シリアライズします。

これは、すべてのCSVファイルが同じ形式、エンコード、行末などを持っていることを前提としています。ヘッダーには改行が埋め込まれていませんが、そうであれば選択肢よりもはるかに高速です。

+0

完璧な答え@ShadowRanger、ありがとう! – mattblack

2

あなたはこれをPythonで行う必要がありますか?

cat a-randomly-selected-csv-file.csv | head -n1 > merged.csv 
for f in *.csv; do cat "`pwd`/$f" | tail -n +2 >> merged.csv; done 
+0

あなたの助けてくれてありがとう - 私はもっと大きなプロジェクトの一環としてPythonでそれを必要とします。乾杯。 – mattblack

+0

@mattblack、私はそれが事実であると考えていたはずです。うまくいけば、アレキサンダーの答えはあなたのために働く! –

0

あなたドン:あなたは完全にシェルでこれを行うに開いている場合は、あなたがする必要があると思い、すべてがランダムに選択された入力からcat最初のヘッダー行は、あなたのワンライナーを実行する前にmerged.csvに.csvファイルでありますこのためにパンダが必要なのですが、単純なcsvモジュールが正常に動作します。

import csv 

df_out_filename = 'df_out.csv' 
write_headers = True 
with open(df_out_filename, 'wb') as fout: 
    writer = csv.writer(fout) 
    for filename in allFiles: 
     with open(filename) as fin: 
      reader = csv.reader(fin) 
      headers = reader.next() 
      if write_headers: 
       write_headers = False # Only write headers once. 
       writer.writerow(headers) 
      writer.writerows(reader) # Write all remaining rows. 
関連する問題