Ich habe viele Monate lang versucht, eine Antwort auf diese Frage zu finden, während ich Pandas lernte. Ich benutze SAS für meine tägliche Arbeit und es ist großartig für die Unterstützung außerhalb des Kerns. SAS ist jedoch aus zahlreichen anderen Gründen als Software schrecklich.
Eines Tages hoffe ich, meine Verwendung von SAS durch Python und Pandas zu ersetzen, aber mir fehlt derzeit ein Out-of-Core-Workflow für große Datenmengen. Ich spreche nicht von "Big Data", für das ein verteiltes Netzwerk erforderlich ist, sondern von Dateien, die zu groß sind, um in den Speicher zu passen, aber klein genug, um auf eine Festplatte zu passen.
Mein erster Gedanke ist, HDFStore
große Datenmengen auf der Festplatte zu speichern und nur die Teile, die ich zur Analyse benötige, in Datenrahmen zu ziehen. Andere haben MongoDB als einfachere Alternative erwähnt. Meine Frage lautet:
Was sind einige Best-Practice-Workflows, um Folgendes zu erreichen:
- Laden von Flatfiles in eine permanente Datenbankstruktur auf der Festplatte
- Abfragen dieser Datenbank, um Daten abzurufen, die in eine Pandas-Datenstruktur eingespeist werden sollen
- Aktualisieren der Datenbank nach dem Manipulieren von Stücken in Pandas
Beispiele aus der Praxis wären sehr willkommen, insbesondere von allen, die Pandas für "große Datenmengen" verwenden.
Bearbeiten - ein Beispiel dafür, wie dies funktionieren soll:
- Importieren Sie iterativ eine große Flat-Datei und speichern Sie sie in einer permanenten Datenbankstruktur auf der Festplatte. Diese Dateien sind normalerweise zu groß, um in den Speicher zu passen.
- Um Pandas verwenden zu können, möchte ich Teilmengen dieser Daten lesen (normalerweise nur wenige Spalten gleichzeitig), die in den Speicher passen.
- Ich würde neue Spalten erstellen, indem ich verschiedene Operationen an den ausgewählten Spalten ausführe.
- Ich müsste dann diese neuen Spalten an die Datenbankstruktur anhängen.
Ich versuche, eine bewährte Methode zur Durchführung dieser Schritte zu finden. Beim Lesen von Links zu Pandas und Pytables scheint das Anhängen einer neuen Spalte ein Problem zu sein.
Bearbeiten - Auf Jeffs Fragen speziell antworten:
- Ich baue Konsumentenkreditrisikomodelle. Die Arten von Daten umfassen Telefon-, SSN- und Adressmerkmale; Eigenschaftswerte; abfällige Informationen wie Strafregister, Insolvenzen usw. Die Datensätze, die ich täglich verwende, enthalten im Durchschnitt fast 1.000 bis 2.000 Felder gemischter Datentypen: kontinuierliche, nominale und ordinale Variablen sowohl für numerische als auch für Zeichendaten. Ich füge selten Zeilen hinzu, aber ich führe viele Operationen aus, die neue Spalten erstellen.
- Typische Operationen umfassen das Kombinieren mehrerer Spalten unter Verwendung der bedingten Logik zu einer neuen zusammengesetzten Spalte. Zum Beispiel
if var1 > 2 then newvar = 'A' elif var2 = 4 then newvar = 'B'
. Das Ergebnis dieser Operationen ist eine neue Spalte für jeden Datensatz in meinem Datensatz. - Abschließend möchte ich diese neuen Spalten an die Datenstruktur auf der Festplatte anhängen. Ich würde Schritt 2 wiederholen und die Daten mit Kreuztabellen und beschreibenden Statistiken untersuchen, um interessante, intuitive Beziehungen zum Modell zu finden.
- Eine typische Projektdatei ist normalerweise ungefähr 1 GB groß. Dateien sind so organisiert, dass eine Zeile aus einer Aufzeichnung von Verbraucherdaten besteht. Jede Zeile hat für jeden Datensatz die gleiche Anzahl von Spalten. Dies wird immer der Fall sein.
- Es ist ziemlich selten, dass ich beim Erstellen einer neuen Spalte nach Zeilen unterteilen würde. Es ist jedoch ziemlich üblich, dass ich beim Erstellen von Berichten oder beim Beschreiben von beschreibenden Statistiken eine Teilmenge von Zeilen unterteile. Zum Beispiel möchte ich möglicherweise eine einfache Frequenz für einen bestimmten Geschäftsbereich erstellen, z. B. Kreditkarten für Privatkunden. Zu diesem Zweck würde ich nur die Datensätze auswählen, in denen der Geschäftsbereich = Einzelhandel ist, zusätzlich zu den Spalten, über die ich berichten möchte. Beim Erstellen neuer Spalten würde ich jedoch alle Datenzeilen und nur die Spalten abrufen, die ich für die Operationen benötige.
- Der Modellierungsprozess erfordert, dass ich jede Spalte analysiere, nach interessanten Beziehungen mit einer Ergebnisvariablen suche und neue zusammengesetzte Spalten erstelle, die diese Beziehungen beschreiben. Die Spalten, die ich untersuche, werden normalerweise in kleinen Mengen erstellt. Zum Beispiel werde ich mich auf eine Reihe von beispielsweise 20 Spalten konzentrieren, die sich nur mit Immobilienwerten befassen, und beobachten, wie sie sich auf den Ausfall eines Kredits beziehen. Sobald diese untersucht und neue Spalten erstellt wurden, gehe ich zu einer anderen Gruppe von Spalten über, z. B. College-Ausbildung, und wiederhole den Vorgang. Ich erstelle Kandidatenvariablen, die die Beziehung zwischen meinen Daten und einem bestimmten Ergebnis erklären. Ganz am Ende dieses Prozesses wende ich einige Lerntechniken an, die aus diesen zusammengesetzten Spalten eine Gleichung erstellen.
Es ist selten, dass ich dem Datensatz jemals Zeilen hinzufügen würde. Ich werde fast immer neue Spalten erstellen (Variablen oder Funktionen in der Statistik / maschinellen Lernsprache).
Antworten:
Ich verwende routinemäßig Dutzende von Gigabyte Daten auf diese Weise, z. B. habe ich Tabellen auf der Festplatte, die ich über Abfragen lese, Daten erstelle und anhänge.
Es lohnt sich, die Dokumente und spät in diesem Thread zu lesen, um einige Vorschläge zum Speichern Ihrer Daten zu erhalten.
Details, die sich auf die Speicherung Ihrer Daten auswirken, z. B.:
Geben Sie so viele Details wie möglich an. und ich kann Ihnen helfen, eine Struktur zu entwickeln.
(Wenn wir ein Spielzeugbeispiel geben, können wir spezifischere Empfehlungen abgeben.)
Lösung
Stellen Sie sicher, dass Sie mindestens Pandas
0.10.1
installiert haben.Lesen Sie iterierende Dateien Stück für Stück und mehrere Tabellenabfragen .
Da pytables für den zeilenweisen Betrieb optimiert ist (was Sie abfragen), erstellen wir für jede Gruppe von Feldern eine Tabelle. Auf diese Weise ist es einfach, eine kleine Gruppe von Feldern auszuwählen (was mit einer großen Tabelle funktioniert, aber es ist effizienter, dies auf diese Weise zu tun ... Ich denke, ich kann diese Einschränkung möglicherweise in Zukunft beheben ... das ist es ohnehin intuitiver):
(Das Folgende ist Pseudocode.)
Lesen Sie die Dateien ein und erstellen Sie den Speicher (im Wesentlichen das, was Sie tun
append_to_multiple
):Jetzt haben Sie alle Tabellen in der Datei (tatsächlich könnten Sie sie in separaten Dateien speichern, wenn Sie möchten, müssten Sie wahrscheinlich den Dateinamen zur group_map hinzufügen, aber wahrscheinlich ist dies nicht erforderlich).
So erhalten Sie Spalten und erstellen neue:
Wenn Sie für die Nachbearbeitung bereit sind:
Über data_columns, brauchen Sie nicht wirklich definieren ANY data_columns; Mit ihnen können Sie Zeilen basierend auf der Spalte unterwählen. ZB so etwas wie:
Sie können für Sie in der Phase der Erstellung des Abschlussberichts am interessantesten sein (im Wesentlichen wird eine Datenspalte von anderen Spalten getrennt, was die Effizienz etwas beeinträchtigen kann, wenn Sie viel definieren).
Vielleicht möchten Sie auch:
Lassen Sie mich wissen, wenn Sie Fragen haben!
quelle
Ich denke, den obigen Antworten fehlt ein einfacher Ansatz, den ich sehr nützlich gefunden habe.
Wenn ich eine Datei habe, die zu groß ist, um sie in den Speicher zu laden, teile ich die Datei in mehrere kleinere Dateien auf (entweder nach Zeilen oder Spalten).
Beispiel: Bei Handelsdaten im Wert von 30 Tagen mit einer Größe von ~ 30 GB zerlege ich sie in eine Datei pro Tag mit einer Größe von ~ 1 GB. Anschließend verarbeite ich jede Datei einzeln und aggregiere die Ergebnisse am Ende
Einer der größten Vorteile besteht darin, dass die Dateien parallel verarbeitet werden können (entweder mehrere Threads oder Prozesse).
Der andere Vorteil ist, dass die Dateimanipulation (wie das Hinzufügen / Entfernen von Datumsangaben im Beispiel) durch reguläre Shell-Befehle erfolgen kann, was in fortgeschritteneren / komplizierteren Dateiformaten nicht möglich ist
Dieser Ansatz deckt nicht alle Szenarien ab, ist jedoch in vielen von ihnen sehr nützlich
quelle
Zwei Jahre nach der Frage gibt es jetzt ein "out-of-core" -Pandas- Äquivalent: dask . Es ist ausgezeichnet! Obwohl es nicht alle Pandas-Funktionen unterstützt, können Sie damit wirklich weit kommen.
quelle
dask
.Wenn Ihre Datensätze zwischen 1 und 20 GB liegen, sollten Sie eine Workstation mit 48 GB RAM erwerben. Dann können Pandas den gesamten Datensatz im RAM speichern. Ich weiß, dass dies nicht die Antwort ist, nach der Sie hier suchen, aber wissenschaftliches Rechnen auf einem Notebook mit 4 GB RAM ist nicht sinnvoll.
quelle
Ich weiß, dass dies ein alter Thread ist, aber ich denke, die Flamme Bibliothek ist einen Besuch wert. Es ist für diese Art von Situationen gebaut.
Aus den Dokumenten:
Blaze erweitert die Benutzerfreundlichkeit von NumPy und Pandas auf verteiltes und Out-of-Core-Computing. Blaze bietet eine ähnliche Schnittstelle wie das NumPy ND-Array oder Pandas DataFrame, ordnet diese bekannten Schnittstellen jedoch einer Vielzahl anderer Computer-Engines wie Postgres oder Spark zu.
Bearbeiten: Übrigens wird es von ContinuumIO und Travis Oliphant, Autor von NumPy, unterstützt.
quelle
Dies ist bei Pymongo der Fall. Ich habe auch Prototypen mit SQL Server, SQLite, HDF, ORM (SQLAlchemy) in Python erstellt. In erster Linie ist Pymongo eine dokumentbasierte Datenbank, daher wäre jede Person ein Dokument (
dict
mit Attributen). Viele Menschen bilden eine Sammlung und Sie können viele Sammlungen haben (Menschen, Börse, Einkommen).pd.dateframe -> pymongo Hinweis: Ich verwende das
chunksize
Inread_csv
, um es auf 5 bis 10.000 Datensätze zu beschränken (Pymongo lässt den Socket fallen, wenn er größer ist).Abfrage: gt = größer als ...
.find()
Gibt einen Iterator zurück, den ich normalerweise verwendeichunked
, um ihn in kleinere Iteratoren zu zerlegen.Wie wäre es mit einem Join, da ich normalerweise 10 Datenquellen zum Einfügen bekomme:
dann (in meinem Fall muss ich manchmal
aJoinDF
erst weitermachen, bevor es "verschmelzbar" ist.)Anschließend können Sie die neuen Informationen über die unten stehende Aktualisierungsmethode in Ihre Hauptsammlung schreiben. (logische Sammlung gegen physische Datenquellen).
Bei kleineren Suchvorgängen einfach denormalisieren. Sie haben beispielsweise Code im Dokument und fügen einfach den Feldcode-Text hinzu und führen beim
dict
Erstellen von Dokumenten eine Suche durch.Jetzt haben Sie einen schönen Datensatz, der auf einer Person basiert. Sie können Ihre Logik für jeden Fall entfesseln und mehr Attribute erstellen. Schließlich können Sie Ihre 3-to-Memory-Max-Schlüsselindikatoren in Pandas einlesen und Pivots / Agg / Daten untersuchen. Dies funktioniert bei mir für 3 Millionen Datensätze mit Zahlen / großem Text / Kategorien / Codes / Floats / ...
Sie können auch die beiden in MongoDB integrierten Methoden verwenden (MapReduce und Aggregat Framework). Weitere Informationen zum Aggregat-Framework finden Sie hier , da es einfacher zu sein scheint als MapReduce und für eine schnelle Aggregatarbeit praktisch ist. Beachten Sie, dass ich meine Felder oder Beziehungen nicht definieren musste und einem Dokument Elemente hinzufügen kann. Beim aktuellen Stand des sich schnell ändernden Numpy-, Pandas- und Python-Toolset hilft mir MongoDB, einfach an die Arbeit zu gehen :)
quelle
In [96]: test.insert((a[1].to_dict() for a in df.iterrows())) --------------- InvalidDocument: Cannot encode object: 0
. Irgendwelche Ideen, was falsch sein könnte? Mein Datenrahmen besteht aus allen int64-D-Typen und ist sehr einfach.Ich habe dies etwas spät entdeckt, arbeite aber mit einem ähnlichen Problem (Hypothekenvorauszahlungsmodelle). Meine Lösung bestand darin, die HDFStore-Ebene von pandas zu überspringen und gerade pytables zu verwenden. Ich speichere jede Spalte als einzelnes HDF5-Array in meiner endgültigen Datei.
Mein grundlegender Workflow besteht darin, zuerst eine CSV-Datei aus der Datenbank abzurufen. Ich gzip es, also ist es nicht so groß. Dann konvertiere ich das in eine zeilenorientierte HDF5-Datei, indem ich es in Python durchlaufe, jede Zeile in einen realen Datentyp konvertiere und in eine HDF5-Datei schreibe. Das dauert einige zehn Minuten, benötigt aber keinen Speicher, da es nur zeilenweise arbeitet. Dann "transponiere" ich die zeilenorientierte HDF5-Datei in eine spaltenorientierte HDF5-Datei.
Die Transponierung der Tabelle sieht folgendermaßen aus:
Das Zurücklesen sieht dann so aus:
Jetzt führe ich dies normalerweise auf einem Computer mit einer Menge Speicher aus, sodass ich bei der Speichernutzung möglicherweise nicht vorsichtig genug bin. Beispielsweise liest die Ladeoperation standardmäßig den gesamten Datensatz.
Das funktioniert im Allgemeinen für mich, aber es ist ein bisschen klobig und ich kann die ausgefallene Pytables-Magie nicht verwenden.
Bearbeiten: Der eigentliche Vorteil dieses Ansatzes gegenüber dem Standard-Pytable-Array mit Datensätzen besteht darin, dass ich die Daten dann mit h5r in R laden kann, das keine Tabellen verarbeiten kann. Zumindest konnte ich es nicht schaffen, heterogene Tabellen zu laden.
quelle
Ein Trick, den ich für Anwendungsfälle mit großen Datenmengen als hilfreich empfand, besteht darin, das Datenvolumen zu reduzieren, indem die Float-Genauigkeit auf 32 Bit reduziert wird. Es ist nicht in allen Fällen anwendbar, aber in vielen Anwendungen ist die 64-Bit-Genauigkeit übertrieben und die 2-fache Speicherersparnis lohnt sich. Um einen offensichtlichen Punkt noch deutlicher zu machen:
quelle
Wie von anderen angemerkt, hat sich nach einigen Jahren ein "Out-of-Core" -Pandas- Äquivalent herausgebildet: dask . Obwohl dask kein Ersatz für Pandas und all seine Funktionen ist, zeichnet es sich aus mehreren Gründen aus:
Dask ist eine flexible Parallel-Computing-Bibliothek für analytisches Computing, die für die dynamische Aufgabenplanung für interaktive Computer-Workloads von „Big Data“ -Sammlungen wie parallele Arrays, Datenrahmen und Listen optimiert ist, die allgemeine Schnittstellen wie NumPy-, Pandas- oder Python-Iteratoren auf größere erweitern. als Speicher oder verteilte Umgebungen und skaliert von Laptops zu Clustern.
und um ein einfaches Codebeispiel hinzuzufügen:
ersetzt einen Pandas-Code wie folgt:
und bietet insbesondere über die
concurrent.futures
Schnittstelle eine allgemeine Infrastruktur für die Übermittlung benutzerdefinierter Aufgaben:quelle
Erwähnenswert ist auch hier Ray ,
ein verteiltes Berechnungsframework, das eine eigene Implementierung für Pandas auf verteilte Weise hat.
Ersetzen Sie einfach den Pandas-Import, und der Code sollte wie folgt funktionieren:
Weitere Details finden Sie hier:
https://rise.cs.berkeley.edu/blog/pandas-on-ray/
quelle
Noch eine Variation
Viele der in Pandas ausgeführten Operationen können auch als Datenbankabfrage ausgeführt werden (SQL, Mongo).
Mit einem RDBMS oder Mongodb können Sie einige der Aggregationen in der DB-Abfrage ausführen (die für große Datenmengen optimiert ist und Cache und Indizes effizient verwendet).
Später können Sie die Nachbearbeitung mit Pandas durchführen.
Der Vorteil dieser Methode besteht darin, dass Sie die DB-Optimierungen für die Arbeit mit großen Datenmengen erhalten und gleichzeitig die Logik in einer deklarativen Syntax auf hoher Ebene definieren - und sich nicht mit den Details der Entscheidung befassen müssen, was im Speicher zu tun ist und was zu tun ist des Kerns.
Und obwohl die Abfragesprache und die Pandas unterschiedlich sind, ist es normalerweise nicht kompliziert, einen Teil der Logik von einem zum anderen zu übersetzen.
quelle
Betrachten Sie Ruffus, wenn Sie den einfachen Weg gehen, eine Datenpipeline zu erstellen, die in mehrere kleinere Dateien unterteilt ist.
quelle
Ich bin kürzlich auf ein ähnliches Problem gestoßen. Ich fand, dass es gut funktioniert, die Daten einfach in Chunks zu lesen und anzuhängen, während ich sie in Chunks auf dieselbe CSV schreibe. Mein Problem bestand darin, eine Datumsspalte basierend auf Informationen in einer anderen Tabelle hinzuzufügen und dabei den Wert bestimmter Spalten wie folgt zu verwenden. Dies kann denjenigen helfen, die von Dask und HDF5 verwirrt sind, aber mit Pandas wie mir besser vertraut sind.
quelle
Ich möchte auf das Vaex-Paket hinweisen.
Schauen Sie sich die Dokumentation an: https://vaex.readthedocs.io/en/latest/ Die API kommt der API von Pandas sehr nahe.
quelle
Warum Pandas? Haben Sie Standard Python ausprobiert ? ?
Die Verwendung von Standardbibliothek Python. Pandas wird auch mit der jüngsten Version der stabilen Version regelmäßig aktualisiert.
Mit der Standard-Python-Bibliothek wird Ihr Code immer ausgeführt.
Eine Möglichkeit besteht darin, eine Vorstellung davon zu haben, wie Ihre Daten gespeichert werden sollen und welche Fragen Sie zu den Daten lösen möchten. Zeichnen Sie dann ein Schema, wie Sie Ihre Daten organisieren können (Think Tables), das Ihnen beim Abfragen der Daten hilft, nicht unbedingt bei der Normalisierung.
Sie können Folgendes nutzen:
Ram und HDD werden mit der Zeit immer billiger und Standard Python 3 ist weit verbreitet und stabil.
quelle
Im Moment arbeite ich "wie" Sie, nur in einem niedrigeren Maßstab, weshalb ich keinen PoC für meinen Vorschlag habe.
Es scheint mir jedoch erfolgreich zu sein, pickle als Caching-System zu verwenden und die Ausführung verschiedener Funktionen in Dateien auszulagern - diese Dateien aus meiner Kommando- / Hauptdatei auszuführen; Zum Beispiel verwende ich eine prepare_use.py, um Objekttypen zu konvertieren, einen Datensatz in Test-, Validierungs- und Vorhersagedatensätze aufzuteilen.
Wie funktioniert Ihr Caching mit Gurke? Ich benutze Strings, um auf Pickle-Dateien zuzugreifen, die dynamisch erstellt werden, abhängig davon, welche Parameter und Datensätze übergeben wurden (damit versuche ich zu erfassen und festzustellen, ob das Programm bereits ausgeführt wurde, indem ich .shape für den Datensatz verwende, dikt für übergeben Parameter). Wenn ich diese Maßnahmen respektiere, erhalte ich einen String, der versucht, eine .pickle-Datei zu finden und zu lesen, und kann, falls gefunden, die Verarbeitungszeit überspringen, um zu der Ausführung zu springen, an der ich gerade arbeite.
Bei der Verwendung von Datenbanken stieß ich auf ähnliche Probleme, weshalb ich Freude an der Verwendung dieser Lösung hatte. Es gibt jedoch mit Sicherheit viele Einschränkungen, z. B. das Speichern großer Pickle-Sets aufgrund von Redundanz. Das Aktualisieren einer Tabelle von vor nach nach einer Transformation kann mit einer ordnungsgemäßen Indizierung durchgeführt werden. Durch die Validierung von Informationen wird ein ganz anderes Buch geöffnet (ich habe versucht, gecrawlte Mietdaten zu konsolidieren und habe die Verwendung einer Datenbank nach 2 Stunden im Grunde genommen eingestellt -, da ich danach gerne zurückgesprungen wäre jeder Transformationsprozess)
Ich hoffe meine 2 Cent helfen dir irgendwie.
Schöne Grüße.
quelle