Ich habe mich gefragt ... Wenn ich beispielsweise eine 400-MB-CSV-Datei in einen Pandas-Datenrahmen lese (mit read_csv oder read_table), gibt es eine Möglichkeit, zu schätzen, wie viel Speicher dies benötigt? Ich versuche nur, ein besseres Gefühl für Datenrahmen und Speicher zu bekommen ...
124
top
und dannShift + M
meine Speichernutzung zu sortieren.x=df.loc[[]]
dauert0.1
(um Nullzeilen zu extrahieren) und außerdem Hunderte von Megabyte Speicher benötigt, genau wie der ursprüngliche Datenrahmen, wahrscheinlich aufgrund von Kopien darunter.Antworten:
df.memory_usage()
gibt zurück, wie viel jede Spalte belegt:Um Indizes einzuschließen, übergeben Sie
index=True
.So erhalten Sie den gesamten Speicherverbrauch:
Durch das Übergeben
deep=True
wird außerdem ein genauerer Bericht zur Speichernutzung erstellt, der die vollständige Nutzung der enthaltenen Objekte berücksichtigt.Dies liegt daran, dass die Speichernutzung keinen Speicher enthält, der von Elementen belegt wird, die keine Komponenten des Arrays sind, wenn
deep=False
(Standardfall).quelle
deep=True
deep=True
memory_usage()
gibt die Speichernutzung in Bytes zurück (wie erwartet).Hier ist ein Vergleich der verschiedenen Methoden -
sys.getsizeof(df)
am einfachsten.In diesem Beispiel
df
handelt es sich um einen Datenrahmen mit 814 Zeilen, 11 Spalten (2 Zoll, 9 Objekte), der aus einem 427-KB-Shapefile gelesen wirdsys.getsizeof (df)
df.memory_usage ()
df.info ()
Druckt Datenrahmeninformationen in stdout. Technisch gesehen handelt es sich hierbei um Kibibyte (KiB), nicht um Kilobyte - wie in der Dokumentzeichenfolge angegeben: "Die Speichernutzung wird in lesbaren Einheiten angezeigt (Basis-2-Darstellung)." Das Erhalten von Bytes würde sich also mit 1024 multiplizieren, z. B. 451,6 KiB = 462.438 Bytes.
quelle
g
bezieht sich der obige Code?df.info(memory_usage="deep")
, es gibt „392,6 MB“, währendsys.getsizeof(df)
unddf.memory_usage(index=True, deep=True).sum()
beide Rückkehr etwa „411718016“ (~ 411MB). Können Sie bitte erklären, warum die 3 Ergebnisse nicht konsistent sind? dankedf.memory_usage(deep=True).sum()
fast das gleiche mit zurückdf.memory_usage(index=True, deep=True).sum()
. In meinem Fall nimmt dasindex
nicht viel Speicher. Interessanterweise fand ich das411718016/1024/1024 = 392.6
, alsodf.info(memory_usage="deep")
kann es verwendet werden2^10
, um Byte in MB zu konvertieren , was mich verwirrt. Trotzdem danke für deine Hilfe: D.df.info
gibt Mebibyte (2 ^ 10) zurück, nicht Megabyte (10 ^ 6) - wird die Antwort ändern.Ich dachte, ich würde mehr Daten in die Diskussion einbringen.
Ich habe eine Reihe von Tests zu diesem Thema durchgeführt.
Durch die Verwendung des Python-
resource
Pakets habe ich die Speichernutzung meines Prozesses erhalten.Und indem
StringIO
ich die CSV in einen Puffer schreibe , kann ich die Größe leicht in Bytes messen.Ich habe zwei Experimente durchgeführt, bei denen jeweils 20 Datenrahmen mit zunehmender Größe zwischen 10.000 und 1.000.000 Zeilen erstellt wurden. Beide haben 10 Spalten.
Im ersten Experiment habe ich nur Floats in meinem Datensatz verwendet.
Auf diese Weise erhöhte sich der Speicher im Vergleich zur CSV-Datei in Abhängigkeit von der Anzahl der Zeilen. (Größe in Megabyte)
Beim zweiten Experiment hatte ich den gleichen Ansatz, aber die Daten im Datensatz bestanden nur aus kurzen Zeichenfolgen.
Es scheint, dass das Verhältnis der Größe des CSV und der Größe des Datenrahmens sehr unterschiedlich sein kann, aber die Größe des Speichers wird immer um den Faktor 2-3 größer sein (für die Rahmengrößen in diesem Experiment).
Ich würde diese Antwort gerne mit weiteren Experimenten vervollständigen. Bitte kommentieren Sie, wenn ich etwas Besonderes ausprobieren soll.
quelle
Sie müssen dies in umgekehrter Reihenfolge tun.
Technisch geht es im Speicher darum (einschließlich der Indizes)
Also 168 MB im Speicher mit einer 400 MB-Datei, 1 MB Zeilen mit 20 Float-Spalten
VIEL kompakter, wenn es als binäre HDF5-Datei geschrieben wird
Die Daten waren zufällig, daher hilft die Komprimierung nicht allzu viel
quelle
read_csv
?iotop
liketop
/ verwenden,htop
um die E / A- Leistung (in Echtzeit) anzusehen.nbytes
wird eine grobe Unterschätzung sein, wenn Sie zB Zeichenfolgen in einem Datenrahmen haben.Wenn Sie die
dtype
s Ihres Arrays kennen, können Sie direkt die Anzahl der Bytes berechnen, die zum Speichern Ihrer Daten + einige für die Python-Objekte selbst benötigt werden. Ein nützliches Attribut vonnumpy
Arrays istnbytes
. Sie können die Anzahl der Bytes aus den Arrays in einem Pandas abrufen,DataFrame
indem Sie dies tunobject
dtype-Arrays speichern 8 Bytes pro Objekt (Objekt-dtype-Arrays speichern einen Zeiger auf ein undurchsichtiges ElementPyObject
). Wenn Sie also Zeichenfolgen in Ihrer CSV haben, müssen Sie berücksichtigen, dassread_csv
diese inobject
dtype-Arrays umgewandelt werden, und Ihre Berechnungen entsprechend anpassen.BEARBEITEN:
Siehe die
numpy
skalare Typen Seite für weitere Details über dieobject
dtype
. Da nur eine Referenz gespeichert ist, müssen Sie auch die Größe des Objekts im Array berücksichtigen. Wie auf dieser Seite angegeben, ähneln Objektarrays Python-list
Objekten.quelle
Ja da ist. Pandas speichert Ihre Daten in zweidimensionalen Numpy-
ndarray
Strukturen, die nach dtypes gruppiert sind.ndarray
ist im Grunde ein rohes C-Array von Daten mit einem kleinen Header. Sie können die Größe also abschätzen, indem Sie die Größe des multiplizierendtype
enthaltenen Arrays mit den Abmessungen des Arrays .Beispiel: Wenn Sie 1000 Zeilen mit 2
np.int32
und 5np.float64
Spalten haben, verfügt Ihr DataFrame über ein 2x1000-np.int32
Array und ein 5x1000-Arraynp.float64
Array.4 Bytes * 2 * 1000 + 8 Bytes * 5 * 1000 = 48000 Bytes
quelle
DataFrame
?pandas
eine sehr effiziente Implementierungread_table
in Cython (es ist viel besser als der Loadtxt des Numpys), daher gehe ich davon aus, dass es die Daten analysiert und direkt in der Cython speichertndarray
.Ich glaube, dies gibt der speicherinternen Größe jedes Objekt in Python. Interna müssen auf Pandas und Numpy überprüft werden
quelle