Ich habe eine wirklich große CSV-Datei, die ich in Pandas wie folgt geöffnet habe ...
import pandas
df = pandas.read_csv('large_txt_file.txt')
Sobald ich dies tue, erhöht sich meine Speichernutzung um 2 GB, was erwartet wird, da diese Datei Millionen von Zeilen enthält. Mein Problem tritt auf, wenn ich diesen Speicher freigeben muss. Ich rannte ....
del df
Meine Speichernutzung ist jedoch nicht gesunken. Ist dies der falsche Ansatz, um den von einem Pandas-Datenrahmen verwendeten Speicher freizugeben? Wenn ja, wie ist der richtige Weg?
gc
Modul auch importieren und aufrufen,gc.collect()
aber er kann den Speicher möglicherweise nicht wiederherstellendel df
wird nicht direkt nach der Erstellung von df aufgerufen, oder? Ich denke, es gibt Verweise auf den df an dem Punkt, an dem Sie den df löschen. Es wird also nicht gelöscht, sondern der Name.df = ''
am Ende deines Codes? Scheint den vom Datenrahmen verwendeten RAM zu löschen.Antworten:
Das Reduzieren der Speichernutzung in Python ist schwierig, da Python den Speicher nicht an das Betriebssystem zurückgibt . Wenn Sie Objekte löschen, steht der Speicher neuen Python-Objekten zur Verfügung, jedoch nicht
free()
dem System ( siehe diese Frage) ).Wenn Sie sich an numerische Numpy-Arrays halten, werden diese freigegeben, Box-Objekte jedoch nicht.
Reduzieren der Anzahl der Datenrahmen
Python hält unseren Speicher auf einem hohen Wasserzeichen, aber wir können die Gesamtzahl der von uns erstellten Datenrahmen reduzieren. Bevorzugen
inplace=True
Sie beim Ändern Ihres Datenrahmens, damit Sie keine Kopien erstellen.Ein weiteres häufiges Problem ist das Festhalten an Kopien zuvor in ipython erstellter Datenrahmen:
Sie können dies beheben, indem Sie eingeben
%reset Out
, um Ihren Verlauf zu löschen. Alternativ können Sie anpassen, wie viel Verlauf ipython aufbewahrtipython --cache-size=5
(Standard ist 1000).Reduzieren der Datenrahmengröße
Vermeiden Sie nach Möglichkeit die Verwendung von Objekt-D-Typen.
Werte mit einem Objekttyp werden eingerahmt. Dies bedeutet, dass das numpy-Array nur einen Zeiger enthält und Sie für jeden Wert in Ihrem Datenrahmen ein vollständiges Python-Objekt auf dem Heap haben. Dies schließt Zeichenfolgen ein.
Während numpy Zeichenfolgen mit fester Größe in Arrays unterstützt, ist dies bei Pandas nicht der Fall ( dies führt zu Verwirrung bei den Benutzern ). Dies kann einen signifikanten Unterschied machen:
Möglicherweise möchten Sie die Verwendung von Zeichenfolgenspalten vermeiden oder eine Möglichkeit finden, Zeichenfolgendaten als Zahlen darzustellen.
Wenn Sie einen Datenrahmen haben, der viele wiederholte Werte enthält (NaN ist sehr häufig), können Sie eine spärliche Datenstruktur verwenden , um die Speichernutzung zu reduzieren:
Anzeigen der Speichernutzung
Sie können die Speichernutzung ( Dokumente ) anzeigen :
Ab Pandas 0.17.1 können Sie auch die
df.info(memory_usage='deep')
Speichernutzung einschließlich der Objekte anzeigen .quelle
Wie in den Kommentaren erwähnt, gibt es einige Dinge zu versuchen:
gc.collect
(@EdChum) kann zum Beispiel Dinge löschen. Zumindest aus meiner Erfahrung funktionieren diese Dinge manchmal und oft nicht.Es gibt jedoch eine Sache, die immer funktioniert, da sie auf Betriebssystem- und nicht auf Sprachebene ausgeführt wird.
Angenommen, Sie haben eine Funktion, die einen riesigen DataFrame zwischenzeitlich erstellt und ein kleineres Ergebnis zurückgibt (das auch ein DataFrame sein kann):
Dann, wenn Sie so etwas tun
Dann wird die Funktion in einem anderen Prozess ausgeführt . Wenn dieser Vorgang abgeschlossen ist, nimmt das Betriebssystem alle verwendeten Ressourcen zurück. Es gibt wirklich nichts, was Python, Pandas, der Müllsammler, tun könnte, um das zu stoppen.
quelle
with multiprocessing.Pool(1) as pool: result = pool.map(huge_intermediate_calc, [something])
Dazu muss der Pool geschlossen werden, sobald dies erledigt ist.Dies löst das Problem, den Speicher für mich freizugeben !!!
Der Datenrahmen wird explizit auf null gesetzt
quelle
del df
wird nicht gelöscht, wenndf
zum Zeitpunkt der Löschung ein Verweis auf die vorhanden ist . Sie müssen also alle Verweise darauf löschendel df
, um den Speicher freizugeben.Daher sollten alle an df gebundenen Instanzen gelöscht werden, um die Speicherbereinigung auszulösen.
Verwenden Sie objgragh , um zu überprüfen, welche Objekte festgehalten werden.
quelle
Es scheint, dass es ein Problem mit glibc gibt, das sich auf die Speicherzuordnung in Pandas auswirkt: https://github.com/pandas-dev/pandas/issues/2659
Der in diesem Problem beschriebene Affen-Patch hat das Problem für mich behoben:
quelle