2017-09-08 2 views
1

ich eine ziemlich große csv haben, wie folgt aussehen:ein Datenrahmen in mehrere Gruppen Splitting und Speichern von CSV-Dateien zu trennen

+---------+---------+ 
| Column1 | Column2 | 
+---------+---------+ 
|  1 | 93644 | 
|  2 | 63246 | 
|  3 | 47790 | 
|  3 | 39644 | 
|  3 | 32585 | 
|  1 | 19593 | 
|  1 | 12707 | 
|  2 | 53480 | 
+---------+---------+ 

Meine Absicht ist es,

  1. In einer neuen Spalte
  2. Fügen Sie einen bestimmten Wert in die Spalte 'NewColumnValue' in jeder Zeile des CSV ein
  3. Sortieren Sie die Datei basierend auf dem Wert in Column1
  4. Split die ursprüngliche CSV in neue Dateien basierend auf dem Inhalt von ‚Column1‘, das Entfernen der Header

Zum Beispiel möchte ich mit mehreren Dateien, um am Ende, die wie folgt aussehen:

+---+-------+----------------+ 
| 1 | 19593 | NewColumnValue | 
| 1 | 93644 | NewColumnValue | 
| 1 | 12707 | NewColumnValue | 
+---+-------+----------------+ 

+---+-------+-----------------+ 
| 2 | 63246 | NewColumnValue | 
| 2 | 53480 | NewColumnValue | 
+---+-------+-----------------+ 

+---+-------+-----------------+ 
| 3 | 47790 | NewColumnValue | 
| 3 | 39644 | NewColumnValue | 
| 3 | 32585 | NewColumnValue | 
+---+-------+-----------------+ 

Ich habe verwaltet diese mit separaten Py-Dateien zu tun:

Schritt 1

# -*- coding: utf-8 -*- 
import pandas as pd 
df = pd.read_csv('source.csv') 
df = df.sort_values('Column1') 
df['NewColumn'] = 'NewColumnValue' 
df.to_csv('ready.csv', index=False, header=False) 

Step2

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

Aber ich würde wirklich gerne lernen, wie alles in einer einzigen .py-Datei zu erreichen. Ich versuchte dies:

# -*- coding: utf-8 -*- 
#This processes a large CSV file. 
#It will dd a new column, populate the new column with a uniform piece of data for each row, sort the CSV, and remove headers 
#Then it will split the single large CSV into multiple CSVs based on the value in column 0 
import pandas as pd 
import csv 
from itertools import groupby 
df = pd.read_csv('source.csv') 
df = df.sort_values('Column1') 
df['NewColumn'] = 'NewColumnValue' 
for key, rows in groupby(csv.reader((df)), 
         lambda row: row[0]): 
    with open("%s.csv" % key, "w") as output: 
     for row in rows: 
      output.write(",".join(row) + "\n") 

aber statt wie beabsichtigt, Es ist mir gibt nach jedem Spaltenkopf namens mehr CSVs.

Ist das passiert, weil ich die Headerzeile entfernt habe, wenn ich separate .py-Dateien verwendet habe, und ich mache es hier nicht? Ich bin nicht wirklich sicher, welche Operation ich tun muss, wenn ich die Dateien spalte, um den Header zu entfernen.

Vielen Dank für die Hilfe ein Selbstlerner Noob.

Antwort

3

Warum nicht einfach groupby Column1 und jede Gruppe speichern?

df = df.sort_values('Column1').assign(NewColumn='NewColumnValue') 
print(df) 

    Column1 Column2  NewColumn 
0  1 93644 NewColumnValue 
5  1 19593 NewColumnValue 
6  1 12707 NewColumnValue 
1  2 63246 NewColumnValue 
7  2 53480 NewColumnValue 
2  3 47790 NewColumnValue 
3  3 39644 NewColumnValue 
4  3 32585 NewColumnValue 

for i, g in df.groupby('Column1'): 
    g.to_csv('{}.csv'.format(i), header=False, index_label=False) 

Dank Unatiel für die improvement. header=False schreibt keine Header und index_label=False schreibt keine Indexspalte.

Dies schafft 3 Dateien:

1.csv 
2.csv 
3.csv 

Jede Daten mit zu jeder Column1 Gruppe entsprechen.

+0

Danke. Und um deine Frage zu beantworten, war es, weil, als ich heute google nach einer Lösung für das Problem suchte, Pandas immer wieder auftauchten. Ich wusste nicht, dass es einen anderen Weg gab :) –

+0

@SteveDallas Np. Wenn Sie sich entscheiden, es zu verwenden, können Sie [diese Antwort akzeptieren] (https://stackoverflow.com/help/someone-answers). –

+0

Ich habe diese Methode ausprobiert und es werden einige seltsame Ausgabedateien erzeugt. Wenn ich meine Datei 13.csv als Beispiel nehme, erzeugt es eine Datei mit Kopfzeilen und zusätzlich scheint es, eine kopflose Spalte mit Daten einzufügen, die ich nicht kenne. z.B. \t + ------ + --------- + --------- + ---------------- + | | Spalte1 | Spalte2 | NeueSpalte | | 6446 | 13 | 36457 | NewColumnValue | + ------ + --------- + --------- + ---------------- + –

0

Sie müssen nicht auf itertools für die Filterung wechseln, pandas hat alle erforderlichen Funktionen eingebaut.

# -*- coding: utf-8 -*- 
import pandas as pd 
df = pd.read_csv('source.csv') 
df = df.sort_values('Column1') # Sorting isn't needed 
df['NewColumn'] = 'NewColumnValue' 
for key in df['Column1'].unique(): # For each value in Column1 
    # These two steps can be combined into a single call 
    # I'll separate for clarity: 
    # 1) filter the dataframe on the unique value 
    dw = df[df['Column1']==key] 
    # 2) write the resulting dataframe without headers 
    dw.to_csv("%s.csv" % key, header=False) 
+0

Danke für die Beantwortung. Es gab mir einen Fehler in Zeile 12, aber nachdem ich es in "dw.to_csv (% s.csv"% key, header = False) geändert habe "es hat gut funktioniert. –

0

pandas.DataFrame unterstützt eine Methode to_csv() es die Daten als CSV zu schreiben. Sie benötigen in diesem Fall kein csv Modul.

import pandas as pd 

df = pd.read_csv('source.csv') 
df = df.sort_values('Column1').set_index('Column1') 
df['NewColumn'] = 'NewColumnValue' 
for key in df.index.unique(): 
    df.loc[key].to_csv('%d.csv' % int(key), header=False) 

for key df.index.unique(): wird Schleife über jeden eindeutigen Wert im Index. In Ihrem Beispiel wird die Schleife über (1, 2 , 3) gelegt. wird sicherstellen, dass die Kopfzeile nicht in die Ausgabedatei geschrieben wird.

Und um zu erklären, warum Sie in Ihrem Beispiel die falsche Ausgabe erhalten, versuchen Sie print(list(df)). Dies sollte alle Spalten in df ausgeben. Aus diesem Grund iteriert for key, rows in csv.reader((df)): über die Spalten in df.

Eigentlich sollten Sie 1 CSV für jede Spalte in Ihrem Dataframe erhalten, und ihre Inhalte sind wahrscheinlich so etwas wie ,[NAME_OF_COLUMN] oder vielleicht ,<itertools.... object at 0x.....>.

+0

Danke für die Antwort. Ich bekomme jedoch einen Syntaxfehler auf: df = df.sort_values ​​('Column1'). Set_index ('Column1') –

+0

Ich bekomme hier keinen Syntaxfehler mit python3. Davon abgesehen ist @ cᴏʟᴅsᴘᴇᴇᴅs Antwort besser, Sie sollten sie stattdessen verwenden. – Unatiel

+0

@SteveDallas Nun, da ich darüber nachdenke, wird 'df =' tatsächlich einen Syntaxfehler ausgeben. Ich glaube, du hast versehentlich eine neue Zeile nach 'df =' hinzugefügt. Ich sehe nicht wirklich, wo der Syntaxfehler in meinem Code sein würde. Ich bin jetzt ein bisschen müde. – Unatiel

Verwandte Themen