python - with - Pandas "Group By" ¿Pregunta sobre datos grandes en HDFStore?
save dataframe python (1)
Aquí hay un ejemplo completo.
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)
Salida
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
Algunas advertencias:
1) Esta metodología tiene sentido si la densidad de su grupo es relativamente baja. En el orden de cientos o miles de grupos. Si obtienes más que eso, hay métodos más eficientes (pero más complicados), y tu función que estás aplicando (en este caso, sum
) se vuelve más restrictiva.
Básicamente iterarías por toda la tienda en grupos, agrupando sobre la marcha, pero manteniendo los grupos solo semi-colapsados (imagina haciendo una media, por lo que necesitarías mantener un total acumulado más una cuenta corriente, luego dividir al final) . Por lo tanto, algunas operaciones serían un poco más complicadas, pero podrían manejar MUCHOS grupos (y es realmente rápido).
2) la eficiencia de esto podría mejorarse guardando las coordenadas (por ejemplo, las ubicaciones del grupo, pero esto es un poco más complicado)
3) multi-agrupamiento no es posible con este esquema (es posible, pero requiere un enfoque más parecido al 2) anterior
4) las columnas que desea agrupar, DEBEN ser un data_column!
5) puede combinar cualquier otro filtro que desee en el btw de selección (que es una manera sneeky de hacer grupos múltiples por cierto, acaba de formar 2 listas únicas de grupo e iterador sobre el producto de ellos, no extremadamente eficiente si tiene muchos de grupos, pero puede funcionar)
HTH
Hazme saber si esto funciona para ti
Tengo alrededor de 7 millones de filas en una HDFStore
con más de 60 columnas. La información es más de lo que puedo caber en la memoria. Estoy buscando agregar los datos en grupos según el valor de una columna "A". La documentación para pandas splitting/aggregating/combining supone que ya tengo todos mis datos en un DataFrame
, pero no puedo leer toda la tienda en un DataFrame
en memoria. ¿Cuál es el enfoque correcto para agrupar datos en un HDFStore
?