2016-07-01 2 views
2

Ich habe eine sehr große CSV-Datei (5 GB), also möchte ich nicht das ganze Ding in den Speicher laden, und ich möchte eine oder mehrere löschen seiner Spalten. Ich habe versucht, den folgenden Code in blaze verwenden, aber alle es taten, war die resultierenden Spalten an die bestehende CSV-Datei anhängen:Löschen von Spalten aus sehr großen CSV-Datei mit Pandas oder Blaze

from blaze import Data, odo 
d = Data("myfile.csv") 
d = d[columns_I_want_to_keep] 
odo(d, "myfile.csv") 

Gibt es eine Möglichkeit entweder Pandas oder Blaze, um nur die Spalten halten ich will und löschen die andere?

+0

tut 'odo' Unterstützung Dateimodi? Wenn ja, versuche 'odo (d," myfile.csv ", mode = 'w +')', um die Datei zu überschreiben – EdChum

+0

Es scheint nicht so @EdChum; Ich habe versucht, beide Modus = "w" und Modus = "w +" ohne Erfolg .... – Alex

Antwort

4

Sie dask.dataframe verwenden können, die Pandas syntaktisch ähnlich ist, aber tut Manipulationen out-of-Core so Speicher sollte kein Problem sein. Außerdem wird der Prozess automatisch parallelisiert und sollte daher schnell sein.

import dask.dataframe as dd 

df = dd.read_csv('myfile.csv', usecols=['col1', 'col2', 'col3']) 
df.to_csv('output.csv', index=False) 

Timings

ich jede Methode bisher auf einem 1,4 GB CSV-Datei geschrieben timed haben. Ich behielt vier Spalten und beließ die Ausgabe-CSV-Datei bei 250 MB.

Mit Dask:

%%timeit 
df = dd.read_csv(f_in, usecols=cols_to_keep) 
df.to_csv(f_out, index=False) 

1 loop, best of 3: 41.8 s per loop 

Pandas Mit:

%%timeit 
chunksize = 10**5 
for chunk in pd.read_csv(f_in, chunksize=chunksize, usecols=cols_to_keep): 
    chunk.to_csv(f_out, mode='a', index=False) 

1 loop, best of 3: 44.2 s per loop 

Mit Python/CSV:

%%timeit 
inc_f = open(f_in, 'r') 
csv_r = csv.reader(inc_f) 
out_f = open(f_out, 'w') 
csv_w = csv.writer(out_f, delimiter=',', lineterminator='\n') 
for row in csv_r: 
    new_row = [row[1], row[5], row[6], row[8]] 
    csv_w.writerow(new_row) 
inc_f.close() 
out_f.close() 

1 loop, best of 3: 1min 1s per loop 
+1

Ich bin überrascht 'df.to_csv ('output.csv', index = False)' sieht zu funktionieren, als ich es versuchte Gemäß [dask Dokumentation] (https://dask.pydata.org/en/latest/dataframe-api.html#dask.dataframe.Series.to_csv) erstellt es mehrere Dateien und Sie können keinen einzelnen Dateinamen angeben aber stattdessen wird es in mehrere Dateien aufgeteilt ("Ein Dateiname pro Partition wird erstellt. Sie können die Dateinamen auf verschiedene Arten angeben."). – citynorman

2

ich würde es auf diese Weise tun:

cols2keep = ['col1','col3','col4','col6'] # columns you want to have in the resulting CSV file 
chunksize = 10**5 # you may want to adjust it ... 
for chunk in pd.read_csv(filename, chunksize=chunksize, usecols=cols2keep): 
    chunk.to_csv('output.csv', mode='a', index=False) 

PS auch Sie von CSV zu PyTables Migration betrachten möchten (HDF5), wenn es für Sie geeignet ist ...

1

ich mit großem csv beschäftigen Dateien viel. Hier ist meine Lösung:

import csv 
fname_in = r'C:\mydir\myfile_in.csv' 
fname_out = r'C:\mydir\myfile_out.csv' 
inc_f = open(fname_in,'r') #open the file for reading 
csv_r = csv.reader(inc_f) # Attach the csv "lens" to the input stream - default is excel dialect 
out_f = open(fname_out,'w') #open the file for writing 
csv_w = csv.writer(out_f, delimiter=',',lineterminator='\n') #attach the csv "lens" to the stream headed to the output file 
for row in csv_r: #Loop Through each row in the input file 
    new_row = row[:] # initialize the output row 
    new_row.pop(5) #Whatever column you wanted to delete 
    csv_w.writerow(new_row) 
inc_f.close() 
out_f.close() 
Verwandte Themen