2015-07-29 8 views
6

Ich habe 5 Millionen Zeilen in einer MySQL DB über das (lokale) Netzwerk (so schnelle Verbindung, nicht im Internet).Laden von 5 Millionen Zeilen in Pandas von MySQL

Die Verbindung zum DB funktioniert gut, aber wenn ich

f = pd.read_sql_query('SELECT * FROM mytable', engine, index_col = 'ID') 

Dies nimmt wirklich lange Zeit zu tun versuchen. Selbst Chunking mit chunksize wird langsam sein. Außerdem weiß ich nicht wirklich, ob es dort hingehört oder Informationen abruft.

Ich möchte für diejenigen, die mit großen Daten in einer DB arbeiten, fragen, wie sie ihre Daten für ihre Pandas-Sitzung abrufen?

Wäre es "intelligenter", zum Beispiel, um die Abfrage auszuführen, eine CSV-Datei mit den Ergebnissen zurückgeben und , dass in Pandas laden? Klingt viel mehr beteiligt als es sein muss.

+1

Nicht 5 Millionen Datensätze abrufen, vor allem für einen großen Tisch, die I/O wird dich töten. – dbugger

+1

@dbugger: Ja, tut mir leid, die Abfrage da oben ist nur ein Beispiel, ich don 'SELECT * FROM table', aber immer noch, wenn ich Chunk, wird die Erstellung des Iterators für eine relativ kleine Teilmenge von Datensätzen (> 10%) nie Ende ... Also ich denke, ich mache etwas falsch mit dem Workflow. Vielen Dank. –

+1

Nur um sicher zu sein, dass nichts anderes falsch ist (abgesehen von der Größe), wenn Sie der Abfrage ein 'LIMIT 100' (oder größer) hinzufügen, funktioniert es wie erwartet? – joris

Antwort

3

Die beste Art der Beladung alle Daten aus einer Tabelle aus -alle-SQL-Datenbank in Pandas ist:

  1. die Daten aus der Datenbank für PostgreSQL, SELECT INTO OUTFILE für MySQL mit COPY Dumping oder ähnlich für andere Dialekte.
  2. Lesen der CSV-Datei mit Pandas mit the pandas.read_csv function

den Stecker Verwenden Sie nur ein paar Zeilen zum Lesen. Die Stärke einer SQL-Datenbank ist ihre Fähigkeit, kleine Datenblöcke basierend auf Indizes zu liefern.

Die Bereitstellung ganzer Tabellen ist etwas, was Sie mit Dumps machen.

+0

Wenn Sie das nicht manuell machen wollen, werfen Sie einen Blick auf 'odo': http://odo.readthedocs.org/en/latest/sql.html#conversions – joris

2

Ich hatte ein ähnliches Problem während der Arbeit mit einer Oracle db (für mich stellte es sich heraus, dass es lange dauerte, alle Daten abzurufen, während dieser Zeit hatte ich keine Ahnung, wie weit es war oder ob es ein Problem gab geht weiter) - meine Lösung bestand darin, die Ergebnisse meiner Abfrage in eine Reihe von CSV-Dateien zu streamen und sie dann in Pandas hochzuladen.

Ich bin mir sicher, es gibt schnellere Möglichkeiten, dies zu tun, aber das funktionierte überraschend gut für Datensätze von etwa 8 Millionen Zeilen.

können Sie den Code sehen ich für easy_query.py an meiner Github Seite verwendet, aber die Kernfunktion ich sah wie folgt aus verwendet:

def SQLCurtoCSV (sqlstring, connstring, filename, chunksize): 
    connection = ora.connect(connstring) 
    cursor = connection.cursor() 
    params = [] 
    cursor.execute(sqlstring, params) 
    cursor.arraysize = 256 
    r=[] 
    c=0 
    i=0 
    for row in cursor: 
     c=c+1 
     r.append(row) 
     if c >= chunksize: 
      c = 0 
      i=i+1 
      df = pd.DataFrame.from_records(r) 
      df.columns = [rec[0] for rec in cursor.description] 
      df.to_csv(filename.replace('%%',str(i)), sep='|') 
      df = None 
      r = [] 
    if i==0: 
     df = pd.DataFrame.from_records(r) 
     df.columns = [rec[0] for rec in cursor.description] 
     df.to_csv(filename.replace('%%',str(i)), sep='|') 
     df = None 
     r = [] 

Der umgebenden Modul importiert cx_Oracle, verschiedene Datenbankhaken/api-Anrufe zur Verfügung zu stellen, aber ich würde erwarten, dass es ähnliche Funktionen gibt, die mit einer ähnlich bereitgestellten MySQL API verfügbar sind.

Was ist nett ist, dass Sie die Dateien in Ihrem gewählten Verzeichnis aufbauen sehen können, so erhalten Sie eine Art von Feedback, ob Ihr Extrakt funktioniert und wie viele Ergebnisse pro Sekunde/Minute/Stunde Sie erwarten können .

Es bedeutet auch, dass Sie die ersten Dateien bearbeiten können, während der Rest abgerufen wird.

Sobald alle Daten in einzelnen Dateien gespeichert sind, können sie mit mehreren Anweisungen pandas.read_csv und pandas.concat in einen einzelnen Pandas-Datenrahmen geladen werden.

+0

Haben Sie das mit' pd.read_sql_query vergleichen? '? Da diese Funktion im Grunde die gleiche Funktion hat (Aufruf von 'execute'' und dann' fetchmany' (wenn chunksize verwendet wird)), würde ich denken, dass 'read_sql_query' einfacher zu benutzen ist und noch schneller. – joris

+0

Ich muss nein sagen, habe ich nicht - aber je nachdem, wie es den chuncksize-Parameter verwaltet, sieht das so aus, als könnte es eine Lösung sein. F: Wie geht es mit dem Chunksize-Parameter um? z.B. Angenommen, meine Abfrage gibt 5 Millionen Zeilen zurück, und chunksize ist 100.000, was wäre das Ergebnis? Ich habe nie wirklich verstanden, wie Chunksize funktioniert. –

+0

[später bearbeiten] Gerade gefunden [this] (http://stackoverflow.com/questions/15555005/get-inferred-dataframe-types-iterative-using-chunksize) was darauf hindeutet, dass es eine Art von Chunking-Objekt gibt, das gestufte Ansichten über ermöglicht ein Master-Datensatz - ja, könnte genau das Richtige sein. –

Verwandte Themen