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
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