Estoy intentando submuestras de filas de un DataFrame según una agrupación. Aquí hay un ejemplo. Digamos que yo defino los siguientes datos:Usando pandas, ¿cómo puedo submuestrear un gran cuadro de datos por grupo de manera eficiente?
from pandas import *
df = DataFrame({'group1' : ["a","b","a","a","b","c","c","c","c",
"c","a","a","a","b","b","b","b"],
'group2' : [1,2,3,4,1,3,5,6,5,4,1,2,3,4,3,2,1],
'value' : ["apple","pear","orange","apple",
"banana","durian","lemon","lime",
"raspberry","durian","peach","nectarine",
"banana","lemon","guava","blackberry","grape"]})
Si el grupo I por group1
y group2
, entonces el número de filas de cada grupo está aquí:
In [190]: df.groupby(['group1','group2'])['value'].agg({'count':len})
Out[190]:
count
a 1 2
2 1
3 2
4 1
b 1 2
2 2
3 1
4 1
c 3 1
4 1
5 2
6 1
(Si hay una manera aún más concisa para compute eso, dígalo por favor.)
Ahora quiero construir un DataFrame que tenga una fila seleccionada al azar de cada grupo. Mi propuesta es hacerlo así:
In [215]: from random import choice
In [216]: grouped = df.groupby(['group1','group2'])
In [217]: subsampled = grouped.apply(lambda x: df.reindex(index=[choice(range(len(x)))]))
In [218]: subsampled.index = range(len(subsampled))
In [219]: subsampled
Out[219]:
group1 group2 value
0 b 2 pear
1 a 1 apple
2 b 2 pear
3 a 1 apple
4 a 1 apple
5 a 1 apple
6 a 1 apple
7 a 1 apple
8 a 1 apple
9 a 1 apple
10 a 1 apple
11 a 1 apple
que funciona. Sin embargo, mis datos reales tienen alrededor de 2,5 millones de filas y 12 columnas. Si hago esto de una manera sucia construyendo mis propias estructuras de datos, puedo completar esta operación en cuestión de segundos. Sin embargo, mi implementación anterior no termina en 30 minutos (y no parece tener memoria limitada). Como nota al margen, cuando traté de implementar esto en R, primero intenté plyr
, que tampoco terminó en un período de tiempo razonable; sin embargo, una solución usando data.table
finalizó muy rápidamente.
¿Cómo hago para que esto funcione rápidamente con pandas
? Quiero amar este paquete, ¡así que por favor ayuda!
He respondido en la lista de correo de pystatsmodels sobre esto. Se me ocurrió la misma solución que sugirió: siendo el autor del paquete, no sé de una mejor manera =) –
@wesm, estaba a punto de publicar su respuesta aquí también. ¡Gracias a todos! –