it-swarm.com.de

Arbeitsabläufe für "große Datenmengen" mit pandas

Ich habe viele Monate lang versucht, eine Antwort auf diese Frage zu finden, während ich Pandas lernte. Ich verwende SAS für meine tägliche Arbeit und es ist großartig für die Unterstützung, die außerhalb des Kerns liegt. Allerdings ist SAS als Software aus zahlreichen anderen Gründen schrecklich.

Ich hoffe, dass ich eines Tages die Verwendung von SAS durch python und Pandas ersetzen kann, aber mir fehlt derzeit ein nicht zum Kern gehörender Workflow für große Datenmengen. Ich spreche nicht von "Big Data", das ein verteiltes Netzwerk erfordert, sondern von Dateien, die zu groß sind, um in den Arbeitsspeicher zu passen, aber klein genug, um auf eine Festplatte zu passen.

Mein erster Gedanke ist, HDFStore zu verwenden, um große Datasets auf der Festplatte zu speichern und nur die Teile, die ich benötige, für die Analyse in Datenrahmen zu ziehen. Andere haben MongoDB als einfach zu verwendende Alternative erwähnt. Meine Frage lautet:

Was sind einige Best-Practice-Workflows, um Folgendes zu erreichen:

  1. Laden von Flatfiles in eine permanente Datenbankstruktur auf der Festplatte
  2. Abfragen dieser Datenbank, um Daten abzurufen, die in eine pandas-Datenstruktur eingespeist werden sollen
  3. Aktualisierung der Datenbank nach der Bearbeitung von Teilen 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 das funktionieren soll:

  1. Importieren Sie iterativ eine große Flat-File und speichern Sie sie in einer permanenten Datenbankstruktur auf der Festplatte. Diese Dateien sind normalerweise zu groß, um in den Arbeitsspeicher zu passen.
  2. Um Pandas verwenden zu können, möchte ich Teilmengen dieser Daten (normalerweise nur wenige Spalten gleichzeitig) lesen, die in den Speicher passen.
  3. Ich würde neue Spalten erstellen, indem ich verschiedene Operationen an den ausgewählten Spalten durchführe.
  4. Ich müsste dann diese neuen Spalten in die Datenbankstruktur anhängen.

Ich versuche, eine Best-Practice-Methode für die Ausfü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 - speziell auf Jeffs Fragen antworten:

  1. Ich baue Verbraucherkredit-Risikomodelle auf. 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: fortlaufende, nominale und ordinale Variablen aus numerischen Daten und Zeichendaten. Ich hänge selten Zeilen an, aber ich führe viele Vorgänge aus, die neue Spalten erstellen.
  2. Typische Operationen umfassen das Kombinieren mehrerer Spalten unter Verwendung von Bedingungslogik zu einer neuen zusammengesetzten Spalte. Zum Beispiel if var1 > 2 then newvar = 'A' Elif var2 = 4 then newvar = 'B'. Das Ergebnis dieser Vorgänge ist eine neue Spalte für jeden Datensatz in meinem Datensatz.
  3. Abschließend möchte ich diese neuen Spalten in die Datenstruktur auf der Festplatte einfügen. Ich würde Schritt 2 wiederholen und die Daten mit Kreuztabellen und beschreibenden Statistiken untersuchen, um interessante, intuitive Beziehungen zum Modell zu finden.
  4. Eine typische Projektdatei hat normalerweise eine Größe von 1 GB. Dateien sind so organisiert, dass eine Zeile aus einem Datensatz von Kundendaten besteht. Jede Zeile hat für jeden Datensatz die gleiche Anzahl von Spalten. Dies wird immer der Fall sein.
  5. Es ist ziemlich selten, dass ich beim Erstellen einer neuen Spalte eine Teilmenge nach Zeilen erstellt habe. Es ist jedoch ziemlich häufig, dass ich beim Erstellen von Berichten oder beim Generieren von beschreibenden Statistiken Teilmengen in Zeilen erstelle. Ich möchte beispielsweise eine einfache Frequenz für einen bestimmten Geschäftsbereich erstellen, z. B. Privatkreditkarten. Zu diesem Zweck würde ich nur die Datensätze auswählen, bei denen die Branche = 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 Vorgänge benötige.
  6. 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 erforsche, werden normalerweise in kleinen Sätzen gemacht. Ich werde mich zum Beispiel auf eine Reihe von etwa 20 Spalten konzentrieren, die sich nur mit Immobilienwerten befassen, und beobachten, wie sie mit dem Ausfall eines Kredits zusammenhängen. Sobald diese erforscht und neue Spalten erstellt sind, gehe ich zu einer anderen Gruppe von Spalten über, z. B. zur Hochschulausbildung, und wiederhole den Vorgang. Ich erstelle Kandidatenvariablen, die die Beziehung zwischen meinen Daten und einem bestimmten Ergebnis erklären. 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üge. Ich werde fast immer neue Spalten erstellen (Variablen oder Features in Statistik/Maschinelles Lernen).

886
Zelazny7

Ich verwende routinemäßig Dutzende von Gigabyte an Daten auf diese Weise, z. Ich habe Tabellen auf der Festplatte, die ich über Abfragen gelesen, Daten erstellt und zurück angehängt habe.

Es lohnt sich, die Dokumentation und spät in diesem Thread zu lesen, um einige Vorschläge zum Speichern Ihrer Daten zu erhalten.

Details, die sich darauf auswirken, wie Sie Ihre Daten speichern, wie:
Geben Sie so viele Details wie möglich an. und ich kann Ihnen helfen, eine Struktur zu entwickeln.

  1. Datengröße, Anzahl der Zeilen, Spalten, Spaltentypen; Hängen Sie Zeilen oder nur Spalten an?
  2. Wie sehen typische Operationen aus? Z.B. Führen Sie eine Abfrage nach Spalten durch, um eine Reihe von Zeilen und bestimmten Spalten auszuwählen, führen Sie dann eine Operation (im Arbeitsspeicher) aus, erstellen Sie neue Spalten, und speichern Sie diese.
    (Mit einem Spielzeugbeispiel könnten wir spezifischere Empfehlungen abgeben.)
  3. Was machen Sie nach dieser Verarbeitung? Ist Schritt 2 ad hoc oder wiederholbar?
  4. Flache Eingabedateien: wie viele, grobe Gesamtgröße in GB. Wie sind diese z. von Aufzeichnungen? Enthält jedes Feld andere Felder oder gibt es Datensätze pro Datei mit allen Feldern in jeder Datei?
  5. Wählen Sie jemals Teilmengen von Zeilen (Datensätzen) basierend auf Kriterien aus (z. B. die Zeilen mit Feld A> 5 auswählen)? Und dann machen Sie etwas, oder wählen Sie einfach die Felder A, B, C mit allen Datensätzen aus (und machen dann etwas)?
  6. Arbeiten Sie an all Ihren Spalten (in Gruppen), oder gibt es einen guten Anteil, den Sie möglicherweise nur für Berichte verwenden (z. B. möchten Sie die Daten behalten, müssen diese Spaltenexplizität jedoch erst nachziehen Endergebniszeit)?

Lösung

Stellen Sie sicher, dass Pandas mindestens 0.10.1 installiert ist.

Lesen Sie Dateien werden Stück für Stück durchlaufen und mehrere Tabellenabfragen .

Da pytables so optimiert ist, dass es zeilenweise ausgeführt wird (was Sie abfragen), erstellen wir eine Tabelle für jede Gruppe von Feldern. Auf diese Weise ist es einfach, eine kleine Gruppe von Feldern auszuwählen (dies funktioniert bei einer großen Tabelle, ist aber effizienter ... Ich denke, ich kann diese Einschränkung in Zukunft möglicherweise beheben ... das ist intuitiver sowieso):
(Das Folgende ist Pseudocode.)

import numpy as np
import pandas as pd

# create a store
store = pd.HDFStore('mystore.h5')

# this is the key to your storage:
#    this maps your fields to a specific group, and defines 
#    what you want to have as data_columns.
#    you might want to create a Nice class wrapping this
#    (as you will want to have this map and its inversion)  
group_map = dict(
    A = dict(fields = ['field_1','field_2',.....], dc = ['field_1',....,'field_5']),
    B = dict(fields = ['field_10',......        ], dc = ['field_10']),
    .....
    REPORTING_ONLY = dict(fields = ['field_1000','field_1001',...], dc = []),

)

group_map_inverted = dict()
for g, v in group_map.items():
    group_map_inverted.update(dict([ (f,g) for f in v['fields'] ]))

Einlesen der Dateien und Erstellen des Speichers (im Wesentlichen das tun, was append_to_multiple tut):

for f in files:
   # read in the file, additional options hmay be necessary here
   # the chunksize is not strictly necessary, you may be able to Slurp each 
   # file into memory in which case just eliminate this part of the loop 
   # (you can also change chunksize if necessary)
   for chunk in pd.read_table(f, chunksize=50000):
       # we are going to append to each table by group
       # we are not going to create indexes at this time
       # but we *ARE* going to create (some) data_columns

       # figure out the field groupings
       for g, v in group_map.items():
             # create the frame for this group
             frame = chunk.reindex(columns = v['fields'], copy = False)    

             # append it
             store.append(g, frame, index=False, data_columns = v['dc'])

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:

frame = store.select(group_that_I_want)
# you can optionally specify:
# columns = a list of the columns IN THAT GROUP (if you wanted to
#     select only say 3 out of the 20 columns in this sub-table)
# and a where clause if you want a subset of the rows

# do calculations on this frame
new_frame = cool_function_on_frame(frame)

# to 'add columns', create a new group (you probably want to
# limit the columns in this new_group to be only NEW ones
# (e.g. so you don't overlap from the other tables)
# add this info to the group_map
store.append(new_group, new_frame.reindex(columns = new_columns_created, copy = False), data_columns = new_columns_created)

Wenn Sie für die Nachbearbeitung bereit sind:

# This may be a bit tricky; and depends what you are actually doing.
# I may need to modify this function to be a bit more general:
report_data = store.select_as_multiple([groups_1,groups_2,.....], where =['field_1>0', 'field_1000=foo'], selector = group_1)

Bei Datenspalten müssen Sie nicht unbedingt BELIEBIGE Datenspalten definieren. Mit ihnen können Sie Zeilen basierend auf der Spalte auswählen. Z.B. so etwas wie:

store.select(group, where = ['field_1000=foo', 'field_1001>0'])

Sie könnten 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 eine Menge definieren).

Vielleicht möchten Sie auch:

  • erstellen Sie eine Funktion, die eine Liste von Feldern aufnimmt, die Gruppen in groups_map nachschlägt, diese dann auswählt und die Ergebnisse verkettet, sodass Sie den resultierenden Frame erhalten (dies ist im Wesentlichen die Aufgabe von select_as_multiple). Auf diese Weise wäre die Struktur für Sie ziemlich transparent.
  • indizes für bestimmte Datenspalten (beschleunigt das Unterteilen von Zeilen erheblich).
  • aktivieren Sie die Komprimierung.

Lass es mich wissen, wenn du Fragen hast!

564
Jeff

Ich denke, den obigen Antworten fehlt ein einfacher Ansatz, den ich als sehr nützlich empfunden habe.

Wenn ich eine Datei habe, die zu groß ist, um sie in den Speicher zu laden, zerlege ich die Datei in mehrere kleinere Dateien (entweder nach Zeile oder Spalten).

Beispiel: Im Falle von Handelsdaten im Wert von 30 Tagen mit einer Größe von ~ 30 GB zerlege ich sie in eine Datei mit einer Größe von ~ 1 GB pro Tag. Ich verarbeite anschließend jede Datei einzeln und fasse die Ergebnisse am Ende zusammen

Einer der größten Vorteile ist, 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 ausgeführt werden 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

121
user1827356

Es gibt jetzt, zwei Jahre nach der Frage, ein "Out-of-Core" pandas Äquivalent: dask . Es ist exzellent! Obwohl es nicht alle pandas Funktionen unterstützt, können Sie wirklich weit kommen.

63
Private

Wenn Ihre Datenmengen zwischen 1 und 20 GB liegen, sollten Sie eine Workstation mit 48 GB RAM erwerben. Dann kann Pandas den gesamten Datensatz im RAM speichern. Ich weiß, es ist nicht die Antwort, die Sie hier suchen, aber wissenschaftliches Rechnen auf einem Notebook mit 4 GB RAM ist nicht sinnvoll.

60
rjurney

Ich weiß, dass dies ein alter Thread ist, aber ich denke, dass die Blaze Bibliothek einen Besuch wert ist. Es ist für diese Art von Situationen gebaut.

Aus den Dokumenten:

Blaze erweitert die Benutzerfreundlichkeit von NumPy und Pandas auf verteiltes und nicht zum Kern gehörendes Computing. Blaze bietet eine ähnliche Schnittstelle wie NumPy ND-Array oder Pandas DataFrame, ordnet diese vertrauten Schnittstellen jedoch einer Vielzahl anderer Computer-Engines wie Postgres oder Spark zu.

Edit: Übrigens wird es von ContinuumIO und Travis Oliphant, dem Autor von NumPy, unterstützt.

51
chishaku

Dies ist der Fall für Pymongo. Ich habe auch mit SQL Server, SQLite, HDF, ORM (SQLAlchemy) in Python Prototypen erstellt. In erster Linie ist Pymongo eine dokumentbasierte Datenbank, daher wäre jede Person ein Dokument (dict von Attributen). Viele Leute bilden eine Sammlung und Sie können viele Sammlungen haben (Leute, Börse, Einkommen).

pd.dateframe -> pymongo Hinweis: Ich verwende chunksize in read_csv, um es auf 5 bis 10.000 Datensätze zu beschränken (pymongo lässt den Sockel fallen, wenn er größer ist)

aCollection.insert((a[1].to_dict() for a in df.iterrows()))

abfrage: gt = größer als ...

pd.DataFrame(list(mongoCollection.find({'anAttribute':{'$gt':2887000, '$lt':2889000}})))

.find() gibt einen Iterator zurück, daher verwende ich normalerweise ichunked, um kleinere Iteratoren zu zerlegen.

Wie wäre es mit einem Join, da ich normalerweise 10 Datenquellen zum Zusammenfügen bekomme:

aJoinDF = pandas.DataFrame(list(mongoCollection.find({'anAttribute':{'$in':Att_Keys}})))

dann (in meinem Fall muss ich manchmal erst auf aJoinDF klicken, bevor es "fusionierbar" ist.)

df = pandas.merge(df, aJoinDF, on=aKey, how='left')

Anschließend können Sie die neuen Informationen über die unten stehende Aktualisierungsmethode in Ihre Hauptsammlung schreiben. (logische Sammlung im Vergleich zu physischen Datenquellen).

collection.update({primarykey:foo},{key:change})

Bei kleineren Suchvorgängen einfach denormalisieren. Sie haben beispielsweise Code im Dokument und fügen einfach den Feldcodetext hinzu und führen beim Erstellen von Dokumenten eine dict -Suche durch.

Jetzt haben Sie einen Nice-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 in pandas Ihre 3-to-Memory-Max-Schlüsselindikatoren einlesen und Pivots/Agg/Data Exploration ausführen. Das funktioniert bei mir für 3 Millionen Datensätze mit Zahlen/Big Text/Kategorien/Codes/Floats/...

Sie können auch die beiden in MongoDB integrierten Methoden verwenden (MapReduce und Aggregate Framework). Weitere Informationen zum Aggregat-Framework finden Sie hier , da es einfacher zu sein scheint als MapReduce und praktisch für die schnelle Arbeit mit Aggregaten ist. Beachten Sie, dass ich meine Felder oder Beziehungen nicht definieren musste und einem Dokument Elemente hinzufügen kann. Nach dem aktuellen Stand der sich schnell ändernden Tools, Pandas, python, hilft mir MongoDB, einfach an die Arbeit zu gehen :)

46

Ich habe dies etwas spät bemerkt, arbeite aber mit einem ähnlichen Problem (Hypotheken-Vorauszahlungsmodelle). Meine Lösung bestand darin, die Ebene pandas HDFStore zu überspringen und gerade pytables zu verwenden. Ich speichere jede Spalte als einzelnes HDF5-Array in meiner endgültigen Datei.

Mein grundlegender Arbeitsablauf besteht darin, zuerst eine CSV-Datei aus der Datenbank abzurufen. Ich gzip es, so ist es nicht so groß. Dann konvertiere ich das in eine zeilenorientierte HDF5-Datei, indem ich in Python darüber iteriere, jede Zeile in einen echten 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 Transponierte Tabelle sieht folgendermaßen aus:

def transpose_table(h_in, table_path, h_out, group_name="data", group_path="/"):
    # Get a reference to the input data.
    tb = h_in.getNode(table_path)
    # Create the output group to hold the columns.
    grp = h_out.createGroup(group_path, group_name, filters=tables.Filters(complevel=1))
    for col_name in tb.colnames:
        logger.debug("Processing %s", col_name)
        # Get the data.
        col_data = tb.col(col_name)
        # Create the output array.
        arr = h_out.createCArray(grp,
                                 col_name,
                                 tables.Atom.from_dtype(col_data.dtype),
                                 col_data.shape)
        # Store the data.
        arr[:] = col_data
    h_out.flush()

Das Zurücklesen sieht dann so aus:

def read_hdf5(hdf5_path, group_path="/data", columns=None):
    """Read a transposed data set from a HDF5 file."""
    if isinstance(hdf5_path, tables.file.File):
        hf = hdf5_path
    else:
        hf = tables.openFile(hdf5_path)

    grp = hf.getNode(group_path)
    if columns is None:
        data = [(child.name, child[:]) for child in grp]
    else:
        data = [(child.name, child[:]) for child in grp if child.name in columns]

    # Convert any float32 columns to float64 for processing.
    for i in range(len(data)):
        name, vec = data[i]
        if vec.dtype == np.float32:
            data[i] = (name, vec.astype(np.float64))

    if not isinstance(hdf5_path, tables.file.File):
        hf.close()
    return pd.DataFrame.from_items(data)

Normalerweise führe ich dies auf einem Computer mit einer Tonne 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 bei mir, ist aber etwas klobig und ich kann die Phantasie der Pytables nicht anwenden.

Bearbeiten: Der eigentliche Vorteil dieses Ansatzes gegenüber dem Standard-Array von Datensatz-Pytabellen besteht darin, dass ich die Daten dann mit h5r, das keine Tabellen verarbeiten kann, in R laden kann. Zumindest konnte ich es nicht zum Laden heterogener Tabellen bringen.

37

Ein Trick, den ich für große Datenmengen als hilfreich empfunden habe, besteht darin, die Datenmenge 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-Präzision übertrieben, und die 2x-Speicherersparnis ist es wert. Um einen offensichtlichen Punkt noch offensichtlicher zu machen:

>>> df = pd.DataFrame(np.random.randn(int(1e8), 5))
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000000 entries, 0 to 99999999
Data columns (total 5 columns):
...
dtypes: float64(5)
memory usage: 3.7 GB

>>> df.astype(np.float32).info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000000 entries, 0 to 99999999
Data columns (total 5 columns):
...
dtypes: float32(5)
memory usage: 1.9 GB
27
ytsaig

Wie von anderen angemerkt, ist nach einigen Jahren ein "Out-of-Core" pandas Äquivalent entstanden: dask . Obwohl dask kein Ersatz für = ist pandas und all seine Funktionen zeichnen 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 Rechenarbeitslasten von Big-Data-Sammlungen wie parallelen Arrays, Datenrahmen und Listen optimiert ist und allgemeine Schnittstellen wie NumPy, Pandas oder Python iteriert in speichergroßen oder verteilten Umgebungen und skaliert von Laptops zu Clustern.

Dask betont die folgenden Tugenden:

  • Bekannt: Enthält ein parallelisiertes NumPy-Array und Pandas DataFrame-Objekte
  • Flexibel: Bietet eine Taskplanungsschnittstelle für benutzerdefinierte Workloads und die Integration in andere Projekte.
  • Native: Aktiviert verteiltes Computing in Pure Python mit Zugriff auf den PyData-Stack.
  • Schnell: Arbeitet mit geringem Overhead, geringer Latenz und minimaler Serialisierung, die für schnelle numerische Algorithmen erforderlich sind
  • Skalierung: Läuft stabil auf Clustern mit 1000 Kernen Skalierung: Einfache Einrichtung und Ausführung auf einem Laptop in einem einzigen Prozess
  • Reaktionsschnell: Entwickelt für interaktives Computing bietet es schnelle Rückmeldungen und Diagnosen, um Menschen zu helfen

und um ein einfaches Codebeispiel hinzuzufügen:

import dask.dataframe as dd
df = dd.read_csv('2015-*-*.csv')
df.groupby(df.user_id).value.mean().compute()

ersetzt etwas pandas wie folgt:

import pandas as pd
df = pd.read_csv('2015-01-01.csv')
df.groupby(df.user_id).value.mean()

und bietet über die concurrent.futures-Schnittstelle eine allgemeine Möglichkeit zur Übermittlung von benutzerdefinierten Aufgaben:

from dask.distributed import Client
client = Client('scheduler:port')

futures = []
for fn in filenames:
    future = client.submit(load, fn)
    futures.append(future)

summary = client.submit(summarize, futures)
summary.result()
15
wp78de

Noch eine Variation

Viele der in pandas ausgeführten Operationen können auch als Datenbankabfrage ausgeführt werden (sql, mongo).

Mit einem RDBMS oder einer 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, während Sie die Logik dennoch 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 pandas unterschiedlich sind, ist es normalerweise nicht kompliziert, einen Teil der Logik von einer in eine andere zu übersetzen.

12
Ophir Yoktan

Erwähnenswert ist hier auch Ray ,
Es ist ein verteiltes Rechenframework, das eine eigene Implementierung für pandas auf verteilte Weise hat.

Ersetzen Sie einfach den pandas -Import und der Code sollte wie folgt funktionieren:

# import pandas as pd
import ray.dataframe as pd

#use pd as usual

weitere Details finden Sie hier:

https://rise.cs.berkeley.edu/blog/pandas-on-ray/

10
lev

Betrachten Sie Ruffus , wenn Sie den einfachen Weg der Erstellung einer Datenpipeline gehen, die in mehrere kleinere Dateien unterteilt ist.

8
Golf Monkey

Ich bin kürzlich auf ein ähnliches Problem gestoßen. Ich fand einfach das Lesen der Daten in Stücken und Anhängen, wie ich es in Stücken auf die gleiche CSV schreibe, funktioniert gut. Mein Problem war das Hinzufügen einer Datumsspalte basierend auf Informationen in einer anderen Tabelle, wobei der Wert bestimmter Spalten wie folgt verwendet wurde. Dies kann denjenigen helfen, die durch dask und hdf5 verwirrt sind, sich aber besser mit pandas auskennen wie ich.

def addDateColumn():
"""Adds time to the daily rainfall data. Reads the csv as chunks of 100k 
   rows at a time and outputs them, appending as needed, to a single csv. 
   Uses the column of the raster names to get the date.
"""
    df = pd.read_csv(pathlist[1]+"CHIRPS_tanz.csv", iterator=True, 
                     chunksize=100000) #read csv file as 100k chunks

    '''Do some stuff'''

    count = 1 #for indexing item in time list 
    for chunk in df: #for each 100k rows
        newtime = [] #empty list to append repeating times for different rows
        toiterate = chunk[chunk.columns[2]] #ID of raster nums to base time
        while count <= toiterate.max():
            for i in toiterate: 
                if i ==count:
                    newtime.append(newyears[count])
            count+=1
        print "Finished", str(chunknum), "chunks"
        chunk["time"] = newtime #create new column in dataframe based on time
        outname = "CHIRPS_tanz_time2.csv"
        #append each output to same csv, using no header
        chunk.to_csv(pathlist[2]+outname, mode='a', header=None, index=None)
6
timpjohns

Ich möchte auf das Vaex-Paket hinweisen.

Vaex ist eine python Bibliothek für langsame Out-of-Core DataFrames (ähnlich wie Pandas), um große tabellarische Datasets zu visualisieren und zu erkunden. Es kann Statistiken wie Mittelwert, Summe, Zählung, Standardabweichung usw. in einem N-dimensionalen Raster von bis zu einer Milliarde (109) Objekte/Zeilen pro Sekunde. Die Visualisierung erfolgt mithilfe von Histogrammen, Dichtediagrammen und 3D-Volumendarstellung, sodass Big Data interaktiv untersucht werden kann. Vaex verwendet Speicherzuordnung, Richtlinien zum Kopieren von Speicherplatz und verzögerte Berechnungen, um eine optimale Leistung zu erzielen (keine Speicherverschwendung).

Schauen Sie sich die Dokumentation an: https://vaex.readthedocs.io/en/latest/ Die API ist der API von Pandas sehr ähnlich.

2
Rob