una seleccionar recorrer nueva insertar filtrar datos data columnas columna agregar python pandas dataframe crosstab pandas-groupby

recorrer - seleccionar columnas pandas python



El valor de Groupby cuenta con los pandas del marco de datos (4)

En lugar de recordar soluciones largas, ¿qué tal la que los pandas ha incorporado para usted?

df.groupby([''id'', ''group'', ''term'']).count()

Tengo el siguiente marco de datos:

df = pd.DataFrame([ (1, 1, ''term1''), (1, 2, ''term2''), (1, 1, ''term1''), (1, 1, ''term2''), (2, 2, ''term3''), (2, 3, ''term1''), (2, 2, ''term1'') ], columns=[''id'', ''group'', ''term''])

Quiero agruparlo por id y group y calcular el número de cada término para este id, par de grupo.

Así que al final obtendré algo como esto:

Pude lograr lo que quería al df.iterrows() todas las filas con df.iterrows() y crear un nuevo marco de datos, pero esto es claramente ineficiente. (Si ayuda, conozco la lista de todos los términos de antemano y hay ~ 10 de ellos).

Parece que tengo que agrupar por y luego contar los valores, así que lo intenté con df.groupby([''id'', ''group'']).value_counts() que no funciona porque value_counts opera en la serie groupby y no un marco de datos.

¿De todos modos puedo lograr esto sin bucles?


Puede usar la crosstab :

print (pd.crosstab([df.id, df.group], df.term)) term term1 term2 term3 id group 1 1 2 1 0 2 0 1 0 2 2 1 0 1 3 1 0 0

Otra solución con groupby con size agregación, remodelando por unstack :

df.groupby([''id'', ''group'', ''term''])[''term''].size().unstack(fill_value=0) term term1 term2 term3 id group 1 1 2 1 0 2 0 1 0 2 2 1 0 1 3 1 0 0

Tiempos :

df = pd.concat([df]*10000).reset_index(drop=True) In [48]: %timeit (df.groupby([''id'', ''group'', ''term'']).size().unstack(fill_value=0)) 100 loops, best of 3: 12.4 ms per loop In [49]: %timeit (df.groupby([''id'', ''group'', ''term''])[''term''].size().unstack(fill_value=0)) 100 loops, best of 3: 12.2 ms per loop


Uso groupby y size

df.groupby([''id'', ''group'', ''term'']).size().unstack(fill_value=0)

Sincronización

1,000,000 filas

df = pd.DataFrame(dict(id=np.random.choice(100, 1000000), group=np.random.choice(20, 1000000), term=np.random.choice(10, 1000000)))


utilizando el método pivot_table() :

In [22]: df.pivot_table(index=[''id'',''group''], columns=''term'', aggfunc=''size'', fill_value=0) Out[22]: term term1 term2 term3 id group 1 1 2 1 0 2 0 1 0 2 2 1 0 1 3 1 0 0

Tiempo contra 700K filas DF:

In [24]: df = pd.concat([df] * 10**5, ignore_index=True) In [25]: df.shape Out[25]: (700000, 3) In [3]: %timeit df.groupby([''id'', ''group'', ''term''])[''term''].size().unstack(fill_value=0) 1 loop, best of 3: 226 ms per loop In [4]: %timeit df.pivot_table(index=[''id'',''group''], columns=''term'', aggfunc=''size'', fill_value=0) 1 loop, best of 3: 236 ms per loop In [5]: %timeit pd.crosstab([df.id, df.group], df.term) 1 loop, best of 3: 355 ms per loop In [6]: %timeit df.groupby([''id'',''group'',''term''])[''term''].size().unstack().fillna(0).astype(int) 1 loop, best of 3: 232 ms per loop In [7]: %timeit df.groupby([''id'', ''group'', ''term'']).size().unstack(fill_value=0) 1 loop, best of 3: 231 ms per loop

Tiempo contra 7M filas DF:

In [9]: df = pd.concat([df] * 10, ignore_index=True) In [10]: df.shape Out[10]: (7000000, 3) In [11]: %timeit df.groupby([''id'', ''group'', ''term''])[''term''].size().unstack(fill_value=0) 1 loop, best of 3: 2.27 s per loop In [12]: %timeit df.pivot_table(index=[''id'',''group''], columns=''term'', aggfunc=''size'', fill_value=0) 1 loop, best of 3: 2.3 s per loop In [13]: %timeit pd.crosstab([df.id, df.group], df.term) 1 loop, best of 3: 3.37 s per loop In [14]: %timeit df.groupby([''id'',''group'',''term''])[''term''].size().unstack().fillna(0).astype(int) 1 loop, best of 3: 2.28 s per loop In [15]: %timeit df.groupby([''id'', ''group'', ''term'']).size().unstack(fill_value=0) 1 loop, best of 3: 1.89 s per loop