2016-12-21 3 views
2

Ich habe eine große CSV-Datei mit Informationen über abgetastete Krankheitserreger, die mehrere verschiedene Arten darstellen. Ich möchte diese CSV-Datei nach Arten aufteilen, also werde ich eine CSV-Datei pro Spezies haben. Die Daten in der Datei sind nicht in einer bestimmten Reihenfolge. Meine CSV-Datei sieht wie folgt aus:Aufteilen einer ungeordneten CSV-Datei auf der Grundlage der Werte in der n-ten Spalte/

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 

Der Name der Art ist am Index 5.

ich diese ursprünglich versucht:

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") 

Aber dies fehlschlägt, weil die Daten nicht bestellt werden Nach Spezies und es gibt kein append-Argument für die Ausgabe (das ist mir bekannt), so dass jedes Mal, wenn das Skript auf einen neuen Eintrag einer Spezies trifft, die es bereits in eine Datei geschrieben hat, die ersten Einträge überschreibt.

Gibt es eine einfache Möglichkeit, die Daten nach Spezies zu sortieren und dann das obige Skript auszuführen oder eine Möglichkeit, die Ausgabe des obigen Skripts an eine Datei anzuhängen, anstatt sie zu überschreiben?

Auch würde ich gerne jede der Ausgabedateien nach der Art, die sie enthalten benannt werden.

Danke.

+0

Sie können dies leicht mit Pandas tun, siehe http://stackoverflow.com/questions/37683085/splitting-csv-file-of-multiple-objects-over-time-by-time-point/37683227#37683227 und http://stackoverflow.com/questions/40789383/python-split-csv-file-according-to-first-character-of-the-first-column/40789645#40789645 – EdChum

+0

Es sollte funktionieren; 'groupby()' gruppiert sich bereits nach dem Schlüssel, unabhängig von der Reihenfolge. Welchen Fehler bekommst du? –

Antwort

2

In Bezug auf Ihren Kommentar: "Es gibt kein append Argument für die Ausgabe (die ich kenne)", können Sie "a" anstelle von "w" verwenden, um an die Datei wie anfügen:

Wahrscheinlich ist nicht der beste Ansatz, denn wenn Sie den Code zwei Mal ausführen, erhalten Sie alles doppelt.

+2

nicht schlecht, aber 1) könnten Sie Ihren Beitrag bearbeiten, damit es besser aussieht und was passiert, wenn Sie den Code zweimal ausführen? –

+0

Darüber hinaus, dank der 'groupby()', werden die Daten bereits nach Schlüssel gruppiert; Folglich wird jede Datei genau einmal geöffnet. –

+0

@Haroldo_OK nicht genau: Wenn Sie die Daten nicht sortieren, öffnet es die Datei viele Male, das ist das Problem. –

2

Sie könnten die CSV-Dateien mit der gleichen Lambda-Funktion sortieren, wie Sie für die groupby operation Verwendung sind:

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) 

Anmerkung:

  1. ich die Schreibroutine neu geschrieben csv Modul als Ausgabe zu verwenden,
  2. Ich habe eine Variable für Ihr Lambda so keine Kopie-Paste
erstellt

Beachten Sie, dass Sie Ihre CSV-Dateien bereinigen müssen, wenn Sie Ihre Eingabedaten ändern. Wenn sich eine Spezies nicht in den neuen Daten befindet, verbleibt die alte CSV-Datei auf der Festplatte. Ich würde auf, dass mit einigen Code wie:

import glob,os 

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

Aber Vorsicht vor dem *.csv Muster, weil es zu groß ist, und es kann ein wenig zu effektiv auf anderen CSV-Dateien :)

Hinweis sein: Diese Methode verwendet sort und ist daher mehr Speicher hungrig. Sie können auch auswählen, dass jede Datei im Append-Modus geöffnet wird, da die andere Lösung Speicher spart, aber mehr Datei-E/A durchführt.

Verwandte Themen