Ich versuche derzeit, Daten aus CSV-Dateien in Python 2.7 mit bis zu 1 Million Zeilen und 200 Spalten zu lesen (Dateien reichen von 100 MB bis 1,6 GB). Ich kann dies (sehr langsam) für Dateien mit weniger als 300.000 Zeilen tun, aber sobald ich darüber hinausgehe, erhalte ich Speicherfehler. Mein Code sieht folgendermaßen aus:
def getdata(filename, criteria):
data=[]
for criterion in criteria:
data.append(getstuff(filename, criteron))
return data
def getstuff(filename, criterion):
import csv
data=[]
with open(filename, "rb") as csvfile:
datareader=csv.reader(csvfile)
for row in datareader:
if row[3]=="column header":
data.append(row)
elif len(data)<2 and row[3]!=criterion:
pass
elif row[3]==criterion:
data.append(row)
else:
return data
Der Grund für die else-Klausel in der Funktion getstuff ist, dass alle Elemente, die dem Kriterium entsprechen, zusammen in der CSV-Datei aufgelistet werden. Daher verlasse ich die Schleife, wenn ich an ihnen vorbeikomme, um Zeit zu sparen.
Meine Fragen sind:
Wie kann ich es schaffen, dass dies mit den größeren Dateien funktioniert?
Kann ich es auf irgendeine Weise schneller machen?
Mein Computer verfügt über 8 GB RAM, 64-Bit-Windows 7, und der Prozessor ist 3,40 GHz (nicht sicher, welche Informationen Sie benötigen).
quelle
Antworten:
Sie lesen alle Zeilen in eine Liste und verarbeiten diese Liste dann. Tu das nicht .
Verarbeiten Sie Ihre Zeilen, während Sie sie produzieren. Wenn Sie zuerst die Daten filtern müssen, verwenden Sie eine Generatorfunktion:
Ich habe auch Ihren Filtertest vereinfacht. Die Logik ist dieselbe, aber prägnanter.
Da Sie nur eine einzelne Folge von Zeilen abgleichen, die dem Kriterium entsprechen, können Sie auch Folgendes verwenden:
Sie können jetzt
getstuff()
direkt eine Schleife durchführen . Machen Sie dasselbe ingetdata()
:Schleifen Sie nun direkt
getdata()
in Ihrem Code:Sie haben jetzt nur noch eine Zeile im Speicher, anstatt Tausende von Zeilen pro Kriterium.
yield
macht eine Funktion zu einer Generatorfunktion , was bedeutet, dass sie keine Arbeit erledigt, bis Sie anfangen, sie zu durchlaufen.quelle
csv.DictReader
? Weil meine Tests an einer 2,5-GB-CSV-Datei zeigen, dass der Versuch, zeilenweise wie folgt zu iterieren, wenn dies verwendet wird, dazu führt,csv.reader
dass der Python-Prozess auf die volle 2,5-GB-Speichernutzung anwächst.Obwohl Martijins Antwort wahrscheinlich die beste ist. Hier finden Sie eine intuitivere Möglichkeit, große CSV-Dateien für Anfänger zu verarbeiten. Auf diese Weise können Sie Gruppen von Zeilen oder Blöcken gleichzeitig verarbeiten.
quelle
Ich mache eine ganze Menge Schwingungsanalysen und schaue mir große Datenmengen an (Dutzende und Hunderte Millionen Punkte). Meine Tests haben gezeigt, dass die Funktion pandas.read_csv () 20- mal schneller ist als numpy.genfromtxt (). Und die Funktion genfromtxt () ist dreimal schneller als die Funktion numpy.loadtxt (). Es scheint, dass Sie Pandas für große Datenmengen benötigen .
Ich habe den Code und die Datensätze, die ich in diesen Tests verwendet habe, in einem Blog veröffentlicht, in dem MATLAB vs Python für die Schwingungsanalyse besprochen wurden .
quelle
Was für mich funktioniert hat und ist superschnell ist
Eine andere funktionierende Lösung ist:
quelle
df_train=df_train.compute()
Zeile in Ihrer ersten Lösung nicht den gesamten Datensatz in den Speicher ... was versucht er nicht zu tun?Für jemanden, der auf diese Frage landet. Die Verwendung von Pandas mit ' Chunksize ' und ' Usecols ' hat mir geholfen, eine riesige Zip-Datei schneller als die anderen vorgeschlagenen Optionen zu lesen.
quelle
Hier ist eine andere Lösung für Python3:
Hier
datareader
ist eine Generatorfunktion.quelle
Wenn Sie Pandas verwenden und über viel RAM verfügen (genug, um die gesamte Datei in den Speicher einzulesen), versuchen Sie es
pd.read_csv
mitlow_memory=False
z.quelle