Ich habe etwa 7 Millionen Zeilen in einem HDFStore
mit mehr als 60 Spalten. Die Daten sind mehr als ich in den Speicher passen kann. Ich versuche, die Daten in Gruppen basierend auf dem Wert einer Spalte "A" zu aggregieren. Die Dokumentation für Pandas splitting/aggregating/combining geht davon aus, dass ich alle meine Daten bereits in einem DataFrame
habe, jedoch kann ich nicht den gesamten Speicher in einen In-Memory DataFrame
einlesen. Was ist der richtige Ansatz zum Gruppieren von Daten in einem HDFStore
?Pandas "Group By" Abfrage auf große Daten in HDFStore?
Antwort
Hier ist ein komplettes Beispiel.
import numpy as np
import pandas as pd
import os
fname = 'groupby.h5'
# create a frame
df = pd.DataFrame({'A': ['foo', 'foo', 'foo', 'foo',
'bar', 'bar', 'bar', 'bar',
'foo', 'foo', 'foo'],
'B': ['one', 'one', 'one', 'two',
'one', 'one', 'one', 'two',
'two', 'two', 'one'],
'C': ['dull', 'dull', 'shiny', 'dull',
'dull', 'shiny', 'shiny', 'dull',
'shiny', 'shiny', 'shiny'],
'D': np.random.randn(11),
'E': np.random.randn(11),
'F': np.random.randn(11)})
# create the store and append, using data_columns where I possibily
# could aggregate
with pd.get_store(fname) as store:
store.append('df',df,data_columns=['A','B','C'])
print "store:\n%s" % store
print "\ndf:\n%s" % store['df']
# get the groups
groups = store.select_column('df','A').unique()
print "\ngroups:%s" % groups
# iterate over the groups and apply my operations
l = []
for g in groups:
grp = store.select('df',where = [ 'A=%s' % g ])
# this is a regular frame, aggregate however you would like
l.append(grp[['D','E','F']].sum())
print "\nresult:\n%s" % pd.concat(l, keys = groups)
os.remove(fname)
Ausgabe
store:
<class 'pandas.io.pytables.HDFStore'>
File path: groupby.h5
/df frame_table (typ->appendable,nrows->11,ncols->6,indexers->[index],dc->[A,B,C])
df:
A B C D E F
0 foo one dull -0.815212 -1.195488 -1.346980
1 foo one dull -1.111686 -1.814385 -0.974327
2 foo one shiny -1.069152 -1.926265 0.360318
3 foo two dull -0.472180 0.698369 -1.007010
4 bar one dull 1.329867 0.709621 1.877898
5 bar one shiny -0.962906 0.489594 -0.663068
6 bar one shiny -0.657922 -0.377705 0.065790
7 bar two dull -0.172245 1.694245 1.374189
8 foo two shiny -0.780877 -2.334895 -2.747404
9 foo two shiny -0.257413 0.577804 -0.159316
10 foo one shiny 0.737597 1.979373 -0.236070
groups:Index([bar, foo], dtype=object)
result:
bar D -0.463206
E 2.515754
F 2.654810
foo D -3.768923
E -4.015488
F -6.110789
dtype: float64
Einige Einschränkungen:
1) Diese Methode ist sinnvoll, wenn Ihre Gruppe Dichte relativ gering ist. In der Größenordnung von Hunderten oder Tausenden von Gruppen. Wenn Sie mehr als das bekommen, gibt es effizientere (aber kompliziertere Methoden), und Ihre Funktion, die Sie anwenden (in diesem Fall sum
), wird restriktiver.
Im Wesentlichen würden Sie Iterator über den gesamten Speicher von Chunks, gruppieren, wie Sie gehen, aber halten Sie die Gruppen nur halb kollabiert (stellen Sie sich ein Mittelwert, so müssten Sie eine laufende Summe plus eine laufende Anzahl halten, dann teilen Am Ende). Einige Operationen wären etwas kniffliger, könnten aber VIELE Gruppen behandeln (und sind sehr schnell).
2) die Effizienz dieses durch das Speichern der Koordinaten (zB die Gruppe Standorte verbessert werden könnte, aber das ist ein bisschen komplizierter)
3) Multi-Gruppierung mit dieser Regelung nicht möglich ist (es ist möglich , erfordert aber einen Ansatz wie 2) über
4) die Spalten, die Sie gruppieren möchten, müssen eine Datenspalte sein!
5) Sie können jeden anderen Filter, den Sie wünschen, in der Auswahl BTW kombinieren (was eine schlaue Art der Multi-Gruppierung btw ist, Sie bilden nur 2 eindeutige Listen der Gruppe und Iterator über das Produkt von ihnen, nicht sehr effizient wenn Sie viele Gruppen haben, können aber funktionieren)
HTH
lassen Sie mich wissen, ob dies für Sie arbeitet
Methode 2 wird hier beschrieben: https://github.com/pydata/pandas/issues/3202 – Jeff
Danke Jeff.Ich würde dir Bonuspunkte geben, wenn ich dieses Beispiel (und einen Link zurück zu SO!) Zum Git-Ticket hinzufügen könnte. – technomalogical
hahha .... froh zu helfen – Jeff
- 1. Effiziente GROUP BY-Abfrage auf numpy recarray
- 2. Erweiterte SQL GROUP BY Abfrage
- 3. Pandas HDFStore seltsames Verhalten
- 4. SQL-Abfrage Group By (Berechnung der Persistenz)
- 5. Mysql GROUP BY Optimierung mit inneren Joins und große Datenmenge
- 6. GROUP BY Anzahl der Zeilen von GROUP BY in MySQL
- 7. T-SQL-Abfrage - GROUP BY-Problem
- 8. Einschränkungen von GROUP BY
- 9. GROUP BY benutzerdefinierte Aggregat
- 10. Count & Group By Konflikt
- 11. Optimieren GROUP BY in hsqldb
- 12. Wie GROUP BY in Firebird
- 13. mit Daten Verwenden von GROUP BY
- 14. MySQL GROUP BY Betreff
- 15. GROUP BY-Fehler - SQL
- 16. GROUP BY/SUM von Shell
- 17. GROUP BY mit CursorLoader
- 18. CakePHP und GROUP BY
- 19. MapReduce und SQL GROUP BY
- 20. Yii2 subquery GROUP BY in aktiver Datensatz
- 21. SQL Group By Bedingung
- 22. MySQL "Group By" und "Order By"
- 23. GROUP BY ID Bereich?
- 24. "Symmetric" GROUP BY auf mehrere Spalten
- 25. Pandas HDFStore Datenrahmen aus dem Speicher entladen
- 26. MySQL SELECT GROUP BY
- 27. LINQ-Abfrage mit GROUP BY und Count (*) in anonymen Typ
- 28. Mysql GROUP BY und ORDER BY DESC
- 29. Mit ORDER BY und GROUP BY zusammen
- 30. Group By Rückkehr Klärung
haben Sie bei http://stackoverflow.com/questions/14262433/large-data sah -work-flows-using-pandas/14287518 # 14287518? Jeffs Antworten sind ein guter Grund für diese Art von Workflow –
Dies wird derzeit als eine zukünftige Verbesserung für Pandas diskutiert. Ich hoffe, dass es eines Tages hinzugefügt wird, da ich SAS schließlich ablegen konnte: https://github.com/pydata/pandas/issues/3202 – Zelazny7
Wie ich die Dokumentation verstehe, unterstützen HDFStores nicht alle Operationen, die auf DataFrames verfügbar sind. Sie könnten versuchen, die Fähigkeiten der Tabellenabfrage [hier] (http://pandas.pydata.org/pandas-docs/dev/io.html#query-via-data-columns) zu verwenden, um manuell jeweils eine Gruppe auszuwählen. – BrenBarn