Ich versuche etwas ziemlich Einfaches zu tun, indem ich eine große CSV-Datei in einen Pandas-Datenrahmen lese.
data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)
Der Code schlägt entweder mit a fehl MemoryError
oder wird einfach nie beendet.
Die Mem-Nutzung im Task-Manager wurde bei 506 MB gestoppt, und nach 5 Minuten ohne Änderung und ohne CPU-Aktivität habe ich sie gestoppt.
Ich benutze Pandas Version 0.11.0.
Mir ist bekannt, dass es früher ein Speicherproblem mit dem Datei-Parser gab, aber laut http://wesmckinney.com/blog/?p=543 sollte dies behoben sein.
Die Datei, die ich zu lesen versuche, ist 366 MB groß. Der obige Code funktioniert, wenn ich die Datei auf etwas Kurzes (25 MB) reduziere.
Es ist auch passiert, dass ich ein Popup bekomme, das mir sagt, dass es nicht an die Adresse 0x1e0baf93 schreiben kann ...
Stacktrace:
Traceback (most recent call last):
File "F:\QA ALM\Python\new WIM data\new WIM data\new_WIM_data.py", line 25, in
<module>
wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 401, in parser_f
return _read(filepath_or_buffer, kwds)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 216, in _read
return parser.read()
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 643, in read
df = DataFrame(col_dict, columns=columns, index=index)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 394, in __init__
mgr = self._init_dict(data, index, columns, dtype=dtype)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 525, in _init_dict
dtype=dtype)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 5338, in _arrays_to_mgr
return create_block_manager_from_arrays(arrays, arr_names, axes)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1820, in create_block_manager_from_arrays
blocks = form_blocks(arrays, names, axes)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1872, in form_blocks
float_blocks = _multi_blockify(float_items, items)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1930, in _multi_blockify
block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1962, in _stack_arrays
stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .
Ein bisschen Hintergrundwissen - Ich versuche, die Leute davon zu überzeugen, dass Python dasselbe wie R kann. Dazu versuche ich, ein R-Skript zu replizieren, das dies tut
data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)
R schafft es nicht nur, die obige Datei einwandfrei zu lesen, sondern liest sogar mehrere dieser Dateien in einer for-Schleife (und macht dann einige Dinge mit den Daten). Wenn Python ein Problem mit Dateien dieser Größe hat, könnte ich einen verlorenen Kampf führen ...
nrows=something small
zu übergebenread_csv
, um sicherzustellen, dass nicht die Größe der Datei Probleme verursacht, was, wie Andy sagte, nicht der Fall sein sollte.csv_chunks = pandas.read_csv(filepath, sep = DELIMITER,skiprows = 1, chunksize = 10000)
und verketten Sie dann die Chunksdf = pandas.concat(chunk for chunk in csv_chunks)
. Ich bin immer noch daran interessiert zu wissen, warum das Lesen auf einmal nicht funktioniert. Für mich scheint dies ein Problem mit dem CSV-Reader zu sein.chunksize=1000
Hack verwende, um die CSV zu lesen, und dann versuche, alle Chunks zu einem großen Datenrahmen zu verketten, explodiert an diesem Punkt der Speicher mit einem etwa 3-4-fachen Speicherbedarf im Vergleich zur Größe der Originaldatei. Hat jemand eine Idee, warum der Datenrahmen explodieren könnte?Antworten:
Windows-Speicherbeschränkung
Speicherfehler treten bei Python häufig auf, wenn die 32-Bit-Version unter Windows verwendet wird. Dies liegt daran, dass 32-Bit-Prozesse standardmäßig nur 2 GB Speicher zum Spielen erhalten .
Tricks zur Reduzierung der Speichernutzung
Wenn Sie in Windows kein 32-Bit-Python verwenden, aber beim Lesen von CSV-Dateien die Speichereffizienz verbessern möchten, gibt es einen Trick.
Die Funktion pandas.read_csv verwendet eine Option namens
dtype
. Auf diese Weise erfahren Pandas, welche Typen in Ihren CSV-Daten vorhanden sind.Wie das funktioniert
Standardmäßig versuchen Pandas zu erraten, welche dtypes Ihre CSV-Datei hat. Dies ist eine sehr schwere Operation, da während der Bestimmung des d-Typs alle Rohdaten als Objekte (Zeichenfolgen) im Speicher gehalten werden müssen.
Beispiel
Angenommen, Ihre CSV sieht folgendermaßen aus:
name, age, birthday Alice, 30, 1985-01-01 Bob, 35, 1980-01-01 Charlie, 25, 1990-01-01
Dieses Beispiel ist natürlich kein Problem beim Einlesen in den Speicher, aber es ist nur ein Beispiel.
Wenn Pandas die obige CSV-Datei ohne dtype-Option lesen würden, würde das Alter als Zeichenfolge im Speicher gespeichert, bis Pandas genügend Zeilen der CSV-Datei gelesen hat, um eine qualifizierte Vermutung anzustellen.
Ich denke, die Standardeinstellung bei Pandas ist das Lesen von 1.000.000 Zeilen, bevor der dtype erraten wird.
Lösung
Indem Sie
dtype={'age':int}
als Option für das.read_csv()
Testament angeben, lassen Sie Pandas wissen, dass das Alter als Zahl interpretiert werden sollte. Das spart Ihnen viel Speicher.Problem mit beschädigten Daten
Wenn Ihre CSV-Datei jedoch wie folgt beschädigt wäre:
name, age, birthday Alice, 30, 1985-01-01 Bob, 35, 1980-01-01 Charlie, 25, 1990-01-01 Dennis, 40+, None-Ur-Bz
Wenn Sie dann angeben,
dtype={'age':int}
wird der.read_csv()
Befehl unterbrochen, da er nicht"40+"
in int umgewandelt werden kann. Bereinigen Sie Ihre Daten also sorgfältig!Hier können Sie sehen, wie viel höher die Speichernutzung eines Pandas-Datenrahmens ist, wenn Floats als Zeichenfolgen beibehalten werden:
Versuch es selber
df = pd.DataFrame(pd.np.random.choice(['1.0', '0.6666667', '150000.1'],(100000, 10))) resource.getrusage(resource.RUSAGE_SELF).ru_maxrss # 224544 (~224 MB) df = pd.DataFrame(pd.np.random.choice([1.0, 0.6666667, 150000.1],(100000, 10))) resource.getrusage(resource.RUSAGE_SELF).ru_maxrss # 79560 (~79 MB)
quelle
read_csv
Funktion macht etwas unglaublich Funky, wäre ich sehr überrascht, wenn die Speichernutzung merklich höher ist.Ich hatte das gleiche Speicherproblem beim einfachen Lesen einer durch Tabulatoren getrennten Textdatei mit einer Größe von etwa 1 GB (über 5,5 Millionen Datensätze) und dies löste das Speicherproblem:
df = pd.read_csv(myfile,sep='\t') # didn't work, memory error df = pd.read_csv(myfile,sep='\t',low_memory=False) # worked fine and in less than 30 seconds
Spyder 3.2.3 Python 2.7.13 64 Bit
quelle
low_memory=False
Ich verwende Pandas auf meiner Linux-Box und habe viele Speicherlecks festgestellt, die erst behoben wurden, nachdem Pandas nach dem Klonen von Github auf die neueste Version aktualisiert wurde.
quelle
Dieses Problem trat auch auf, wenn ich in einer virtuellen Maschine ausgeführt wurde oder an einem anderen Ort, an dem der Speicher stark eingeschränkt ist. Es hat nichts mit Pandas oder Numpy oder CSV zu tun, wird aber immer dann auftreten, wenn Sie versuchen, mehr Speicher zu verwenden, als Sie verwenden dürfen, nicht einmal nur in Python.
Die einzige Chance, die Sie haben, ist das, was Sie bereits versucht haben. Versuchen Sie, das große Ding in kleinere Stücke zu zerlegen, die in die Erinnerung passen.
Wenn Sie sich jemals gefragt haben, worum es bei MapReduce geht, haben Sie es selbst herausgefunden ... MapReduce würde versuchen, die Chunks auf viele Maschinen zu verteilen, und Sie würden versuchen, die Chunke nacheinander auf einer Maschine zu verarbeiten.
Was Sie bei der Verkettung der Chunk-Dateien herausgefunden haben, könnte in der Tat ein Problem sein, vielleicht wird bei diesem Vorgang eine Kopie benötigt ... aber am Ende erspart dies Ihnen möglicherweise Ihre aktuelle Situation, aber wenn Ihre CSV etwas größer wird Sie könnten wieder gegen diese Wand laufen ...
Es könnte auch sein, dass Pandas so schlau sind, dass sie die einzelnen Datenblöcke tatsächlich nur dann in den Speicher laden, wenn Sie etwas damit tun, wie die Verkettung mit einem großen df?
Verschiedene Dinge, die Sie ausprobieren können:
quelle
Es gibt keinen Fehler für Pandas 0.12.0 und NumPy 1.8.0.
Ich habe es geschafft, einen großen DataFrame zu erstellen, ihn in einer CSV-Datei zu speichern und ihn dann erfolgreich zu lesen. Bitte sehen Sie das Beispiel hier . Die Größe der Datei beträgt 554 MB (es funktionierte sogar für 1,1-GB-Dateien, dauerte länger, um eine Nutzungshäufigkeit von 1,1-GB-Dateien von 30 Sekunden zu generieren). Obwohl ich 4 GB RAM zur Verfügung habe.
Mein Vorschlag ist, Pandas zu aktualisieren. Eine andere nützliche Sache ist, dass Sie versuchen, Ihr Skript über die Befehlszeile auszuführen, da Sie für R kein Visual Studio verwenden (dies wurde bereits in den Kommentaren zu Ihrer Frage vorgeschlagen), sodass mehr Ressourcen verfügbar sind.
quelle
Ich habe es
chunksize
beim Lesen einer großen CSV-Datei versuchtreader = pd.read_csv(filePath,chunksize=1000000,low_memory=False,header=0)
Das Lesen ist jetzt die Liste. Wir können das wiederholen
reader
und an die neue CSV schreiben / anhängen oder jede Operation ausführenfor chunk in reader: print(newChunk.columns) print("Chunk -> File process") with open(destination, 'a') as f: newChunk.to_csv(f, header=False,sep='\t',index=False) print("Chunk appended to the file")
quelle
Fügen Sie diese hinzu: reviews = pd.read_csv (..., low_memory = False, memory_map = True )
Mein Gedächtnis mit diesen beiden: # 319.082.496 Ohne diese beiden: # 349.110.272
quelle
Obwohl dies eine Problemumgehung ist, die weniger als eine Lösung ist, würde ich versuchen, diese CSV in JSON zu konvertieren (sollte trivial sein) und stattdessen eine
read_json
Methode verwenden - ich habe in Pandas beträchtliche JSON / Datenrahmen (100 MB) geschrieben und gelesen Weg ohne Probleme überhaupt.quelle