Was ist die effizienteste Methode zum konvertieren eines MySQL-ResultSet in ein NumPy-array?
Ich bin mit MySQLdb und Python. Ich habe einige grundlegenden Fragen wie diese:
c=db.cursor()
c.execute("SELECT id, rating from video")
results = c.fetchall()
Brauche ich "Ergebnisse" in ein NumPy-array, und ich bin auf der Suche um wirtschaftlich zu sein mit meinem Arbeitsspeicher Verbrauch. Es scheint, wie das kopieren der Daten Zeile für Zeile wäre unglaublich ineffizient (das doppelte der Speicher wäre notwendig). Gibt es einen besseren Weg, um zu konvertieren MySQLdb Abfrage-Ergebnisse in den NumPy-array-format?
Der Grund, warum ich suchen, um den NumPy-array-format ist, denn ich möchte in der Lage sein, um slice und dice die Daten einfach, und es scheint nicht, wie python ist sehr freundlich zu multi-dimensional arrays in dieser Hinsicht.
e.g. b = a[a[:,2]==1]
Dank!
InformationsquelleAutor thegreatt | 2011-08-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
fetchall
Methode tatsächlich liefert einen iterator, und numpy hat die fromiter Methode, um ein array zu initialisieren aus einem interator. Also, je nachdem, welche Daten in die Tabelle, die Sie kombinieren könnte den beiden einfach, oder verwenden Sie einen adapter-generator.Fromiter erzeugt nur ein 1-d array-Objekt, obwohl, Recht? In diesem Beispiel wir bräuchten eine 2-d.. ich nehme an, Sie konvertieren konnte es irgendwie, aber in diesem Fall wäre dies immer noch die effizienteste Methode?
Ja, Sie können neu zu gestalten es anschließend wieder ein.
Numpy-arrays sind sehr effizient, dass Art und Weise. Sie können das Form-Attribut auf ein Tupel
(2,)
und das sollte funktionieren.Hallo Keith, vielen Dank für diese info - froh zu wissen, Numpy kann diese anmutig. Leider bin ich zu kämpfen mit den fromiter () - Funktion empfehlen Sie die..
results = c.fetchall()
D = np.fromiter(results, dtype=float, count=-1)
gibtValueError: setting an array element with a sequence.
. Scheint nicht egal, ob Ergebnisse von 1D-oder 2D - irgendwelche Ideen?InformationsquelleAutor Keith
Diese Lösung verwendet Kieth ist fromiter Technik, sondern behandelt die zweidimensionale Tabellenstruktur der SQL-Ergebnisse mehr intuitiv. Auch verbessert es auf Doug ' s Methode durch die Vermeidung von alle die Umformung und Abflachung in python-Datentypen. Mit einem structured array können wir Lesen so ziemlich direkt aus der MySQL-Ergebnis in numpy, Ausschneiden python-Datentypen fast ganz. Ich sage 'fast', weil die fetchall iterator noch produziert python-Tupel.
Gibt es eine Einschränkung zwar, aber es ist nicht ein großes Problem. Sie müssen wissen, den Datentyp der Spalten und die Anzahl der Zeilen im Voraus.
Wissen, die Spalte sollte offensichtlich sein, da Sie wissen, was die Abfrage ist vermutlich, ansonsten können Sie immer verwenden, curs.Beschreibung und Karte der MySQLdb.FIELD_TYPE.* Konstanten.
Wissen, dass die Zeilenanzahl bedeutet, dass Sie müssen verwenden Sie client-cursor (das ist der Standard). Ich weiß nicht genug über die Interna von MySQLdb und die MySQL-client-Bibliotheken, aber mein Verständnis ist, dass das gesamte Ergebnis geholt in client-side-Speicher, wenn Sie client-Cursor verwenden, obwohl ich vermute, es gibt tatsächlich einige, die Pufferung und Zwischenspeicherung beteiligt. Dies würde bedeuten, mit Doppel-Speicher für das Ergebnis, wenn für den cursor Kopie und einmal für das array kopieren, so ist es wahrscheinlich eine gute Idee, schließen Sie den cursor so schnell wie möglich, den Speicher freizugeben, wenn die Ergebnismenge groß ist.
Streng genommen, Sie habe nicht die Anzahl der Zeilen im Voraus, aber damit bedeutet das-array Speicher reserviert einmal im Voraus, und nicht kontinuierlich angepasst, sobald weitere Zeilen kommen von der iterator das gemeint wird, um bieten einen enormen performance-Schub.
Und mit einigen code
Finden Sie in der numpy-Dokumentation "dtype" und den link oben zu strukturierten arrays für die, wie Sie angeben, Spalte Datentypen und Spaltennamen.
ndarray_data = A.view(np.int32).reshape((len(A),-1))
Ersetzen Sie die beste Art für alle Ihre Daten.InformationsquelleAutor sirlark
NumPy ist fromiter Methode scheint am besten hier (wie auch in Keith ' s Antwort, die vor diesem).
Mit fromiter Neufassung ein ResultSet zurückgegeben, das durch einen Aufruf einer MySQLdb cursor-Methode, um ein NumPy-array ist einfach, aber es gibt ein paar details, die vielleicht erwähnenswert.
Beachten Sie, dass fromiter gibt eine 1D NumPY-array,
(Dies macht Sinn, natürlich, weil Sie verwenden können fromiter Rückkehr nur einen Teil einer einzigen MySQL-Tabelle, Zeile, durch die übergabe eines Parameters für zählen).
Immer noch, müssen Sie zum wiederherstellen der 2D-Form, daher das Prädikat Aufruf der cursor-Methode rowcount. und der nachfolgende Aufruf Umformen in der letzten Zeile.
Schließlich die default argument für den parameter zählen ist '-1', die nur ruft die ganze durchsuchbar
c.execute("SELECT id, rating FROM video")
results = c.fetchall()
num_rows = int(c.rowcount)
D = np.fromiter(iterable=results, dtype=float, count=-1)
D = D.reshape(num_rows, -1)
bearbeitet meine Antwort zu gehören die Zwischenschritte der Umformung und Abflachung "Ergebnisse". Zum speichern der Eingabe, ich habe nicht diese triviale Schritte in meiner ursprünglichen Antwort, anstatt nur unter Angabe in einem Kommentar, "'Ergebnis' ist ein geschachtelter Tupel"
InformationsquelleAutor doug