Ich habe einige Daten mit Pandas manipuliert und möchte jetzt eine Stapelspeicherung in der Datenbank durchführen. Dies erfordert, dass ich den Datenrahmen in ein Array von Tupeln konvertiere, wobei jedes Tupel einer "Zeile" des Datenrahmens entspricht.
Mein DataFrame sieht ungefähr so aus:
In [182]: data_set
Out[182]:
index data_date data_1 data_2
0 14303 2012-02-17 24.75 25.03
1 12009 2012-02-16 25.00 25.07
2 11830 2012-02-15 24.99 25.15
3 6274 2012-02-14 24.68 25.05
4 2302 2012-02-13 24.62 24.77
5 14085 2012-02-10 24.38 24.61
Ich möchte es in eine Reihe von Tupeln konvertieren wie:
[(datetime.date(2012,2,17),24.75,25.03),
(datetime.date(2012,2,16),25.00,25.07),
...etc. ]
Irgendwelche Vorschläge, wie ich das effizient machen kann?
list(df.itertuples(index=False, name=None))
df.to_records(index=False)
und eine Liste von Diktaten:df.to_dict('records')
Antworten:
Wie wäre es mit:
für Pandas <0,24 verwenden
quelle
.itertuples
effizienter, als die Werte als Array abzurufen und in ein Tupel umzuwandeln.Ab 17.1 wird oben eine Liste der benannten Tupel zurückgegeben .
Wenn Sie eine Liste gewöhnlicher Tupel wünschen, übergeben Sie
name=None
als Argument:quelle
tuple
s in Ihremzip
Iterator (anstelle vonnamedtuple
s) wollen, dann rufen Sie an:data_set.itertuples(index=False, name=None)
itertuples
ist langsam . Vermeiden Sie wenn möglich. For-Schleifen (wie gezeigt die akzeptierte Antwort) sind in diesen Fällen normalerweise schneller.Ein generischer Weg:
quelle
data_set.to_records(index=False).tolist()
besserMotivation
Viele Datensätze sind groß genug, um uns mit Geschwindigkeit / Effizienz zu befassen. Deshalb biete ich diese Lösung in diesem Sinne an. Es ist auch kurz und bündig.
Lassen Sie uns zum Vergleich die
index
Spalte fallenLösung
Ich werde die Verwendung von
zip
und vorschlagenmap
Es ist auch flexibel, wenn wir uns mit einer bestimmten Teilmenge von Spalten befassen möchten. Wir gehen davon aus, dass die Spalten, die wir bereits angezeigt haben, die gewünschte Teilmenge sind.
Was ist schneller?
Am
records
schnellsten stellt sich heraus, gefolgt von einer asymptotischen Konvergenzzipmap
unditer_tuples
Ich werde eine Bibliothek verwenden
simple_benchmarks
, die ich aus diesem Beitrag erhalten habeÜberprüfen Sie die Ergebnisse
quelle
Hier ist ein vektorisiert Ansatz (vorausgesetzt , den Datenrahmen,
data_set
wie definiert wirddf
statt) , dass die Renditen eineslist
vontuples
wie gezeigt:produziert:
Die Idee, die Datum / Uhrzeit-Spalte als Indexachse festzulegen, besteht darin, die Konvertierung des
Timestamp
Werts in das entsprechendedatetime.datetime
Format zu erleichtern, indem dasconvert_datetime64
Argument verwendet wird, inDF.to_records
dem dies für a giltDateTimeIndex
erleichtern, Datenrahmen geschieht.Dies gibt eine zurück,
recarray
die dann dazu gebracht werden könnte, einelist
Verwendung zurückzugeben.tolist
Eine allgemeinere Lösung in Abhängigkeit vom Anwendungsfall wäre:
quelle
Der effizienteste und einfachste Weg:
Sie können die Spalten filtern, die Sie vor diesem Aufruf benötigen.
quelle
Diese Antwort fügt keine Antworten hinzu, die noch nicht besprochen wurden, aber hier sind einige Geschwindigkeitsergebnisse. Ich denke, dies sollte Fragen lösen, die in den Kommentaren auftauchten. Alle diese Werte sehen aus wie O (n) , basierend auf diesen drei Werten.
TL; DR :
tuples = list(df.itertuples(index=False, name=None))
undtuples = list(zip(*[df[c].values.tolist() for c in df]))
sind für die schnellsten gebunden.Ich habe hier einen schnellen Geschwindigkeitstest mit den Ergebnissen für drei Vorschläge durchgeführt:
tuples = list(zip(*[df[c].values.tolist() for c in df]))
tuples = [tuple(x) for x in df.values]
name=None
Vorschlag von @Axel:tuples = list(df.itertuples(index=False, name=None))
Kleine Größe:
Gibt:
Größer:
Gibt:
So viel Geduld wie ich habe:
Gibt:
Die Zip-Version und die Itertuples-Version liegen innerhalb der Konfidenzintervalle zueinander. Ich vermute, dass sie unter der Haube dasselbe tun.
Diese Geschwindigkeitstests sind jedoch wahrscheinlich irrelevant. Das Überschreiten der Speichergrenzen meines Computers nimmt nicht viel Zeit in Anspruch , und Sie sollten dies bei einem großen Datensatz wirklich nicht tun. Die Arbeit mit diesen Tupeln danach wird wirklich ineffizient sein. Es ist unwahrscheinlich, dass Ihr Code einen großen Engpass darstellt. Halten Sie sich also einfach an die Version, die Sie für am besten lesbar halten.
quelle
[*zip(*map(df.get, df))]
. Ich dachte, du findest es interessant.quelle
Mehr pythonischer Weg:
quelle
map()
ist notorisch unpythonisch.Ändern der Datenrahmenliste in eine Liste von Tupeln.
quelle