2016-12-21 5 views
2

私はいくつかの異なる種を表すサンプリングされた病原体に関する情報を含む大きなcsvファイルを持っています。種によってこのCSVファイルを分割したいので、種ごとに1つのCSVファイルを作成します。ファイル内のデータは、特定の順序ではありません。私のcsvファイルは次のようになります。n番目の列の値に基づいて順序付けされていないcsvファイルを分割する/

maa_2015-10-07_15-15-16_5425_manifest.csv,NULL,ERS044420,EQUI0208,1336,Streptococcus equi,15/10/2010,2010,Belgium,Belgium 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852528,2789STDY5834916,154046,Hungatella hathewayi,2013,2013,United Kingdom,UK 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852530,2789STDY5834918,33039,Ruminococcus torques,2013,2013,United Kingdom,UK 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852533,2789STDY5834921,40520,Blautia obeum,2013,2013,United Kingdom,UK 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852535,2789STDY5834923,1150298,Fusicatenibacter saccharivorans,2013,2013,United Kingdom,UK 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852537,2789STDY5834925,1407607,Fusicatenibacter,2013,2013,United Kingdom,UK 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852540,2789STDY5834928,39492,Eubacterium siraeum,2013,2013,United Kingdom,UK 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852544,2789STDY5834932,292800,Flavonifractor plautii,2013,2013,United Kingdom,UK 
maa_2015-09-28_13-07-45_0098_manifest.csv,NULL,ERS852551,2789STDY5834939,169435,Anaerotruncus colihominis,2013,2013,United Kingdom,UK 
maa_2015-10-07_15-15-16_5425_manifest.csv,NULL,ERS044418,EQUI0206,1336,Streptococcus equi,05/02/2010,2010,Belgium,Belgium 
maa_2015-10-07_15-15-16_5425_manifest.csv,NULL,ERS044419,EQUI0207,1336,Streptococcus equi,29/07/2010,2010,Belgium,Belgium 

種の名前は、私はもともと、この試みた5

指標である:

import csv 
from itertools import groupby 

for key, rows in groupby(csv.reader(open("file.csv")), 
         lambda row: row[5]): 
    with open("%s.csv" % key, "w") as output: 
     for row in rows: 
      output.write(",".join(row) + "\n") 

をしかし、データが発注されていないため、これは失敗します(私が知っている)出力のための追加の引数はありませんので、スクリプトが既にファイルに書き込んだ種の新しいエントリに遭遇するたびに、最初のエントリを上書きします。

種別でデータを並べ替えて上のスクリプトを実行するか、上のスクリプトの出力を上書きするのではなくファイルに追加する簡単な方法はありますか?

また、出力ファイルのそれぞれに含まれている種の名前を付けるのが理想的です。

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

+0

これは簡単にパンダで行うことができます。http://stackoverflow.com/questions/37683085/splitting-csv-file-of-multiple-objects-over-time-by-time-point/37683227#37683227 http://stackoverflow.com/questions/40789383/python-split-csv-file-according-to-first-character-of-the-first-column/40789645#40789645 – EdChum

+0

これは動作するはずです。 'groupby()'は既にキーに基づいて、順序にかかわらずグループ化されています。あなたはどんなエラーを出していますか? –

答えて

2

あなたのコメントを参照してください: "出力のための追加引数がありません"、あなたのようなファイルに追加するために 'w'の代わりに 'a'を使用することができます:

with open("%s.csv" % key, "a") 

コードを2回実行すると、すべてが2倍になるため、おそらく最良の方法ではありません。あなたがgroupby operationのために使用しているよう

+2

でも悪くないですが、1)あなたの投稿を編集して見栄えが良くなり、コードを2回実行するとどうなりますか? –

+0

さらに、 'groupby()'のおかげで、データは既にkeyでグループ化されています。その結果、各ファイルは正確に1回だけ開くことになります。 –

+0

@Haroldo_OK正確には:データをソートしないと、何度もファイルが開きますが、それは問題です。 –

2

あなたは同じラムダ関数を使用してCSVファイルを並べ替えることができます:

import csv 
from itertools import groupby 

groupfunc = lambda row: row[5] 

for key, rows in groupby(sorted(csv.reader(open("file.csv")),key=groupfunc),groupfunc): 
    with open("%s.csv" % key, "w") as output: 
     cw = csv.writer(output) 
     cw.writerows(rows) 

注:私は出力としてcsvモジュールを使用する書き込みルーチンを書き直し

  1. ラムダの変数を作成してコピー・ペーストしないようにしました。

入力データを変更する場合は、新しいデータに1つの種がない場合、古いcsvがディスクに残るため、csvファイルをクリーンアップする必要があります。私のようないくつかのコードを持つものになります

import glob,os 

for f in glob.glob("*.csv"): 
    os.remove(f) 

しかし、それはあまりにも広いですので、*.csvパターンの用心、それはあなたの他のCSVファイルに少しも有効であろう:)

注:このメソッドは、用途をsortであり、したがって、より多くのメモリが空いています。メモリを節約することを示唆しているが、ファイルI/Oをさらに実行する方法として、代わりに各ファイルを追加モードで開くこともできます。

関連する問題