El siguiente código me da un keyError: 0. Funciona si elimino la parte [0].

Tenga en cuenta que lo que realmente quería hacer es tomar cada subcuadro de datos en el grupo, hacer alguna manipulación (que, por ejemplo, implica el cálculo entre filas y entre columnas) y devolver un nuevo marco de datos. Es similar a las operaciones ddply o data.table groupby en R.

import pandas as pd
df = pd.DataFrame(dict(a=list('XYXYXYXY'), b=list('AABBCCDD')))
df.groupby('a').apply(lambda x: x['b'][0])

Resultados:

KeyError                                  Traceback (most recent call last)
<ipython-input-136-7b87ffbc2fd2> in <module>() 
      1 df = pd.DataFrame(dict(a=list('XYXYXYXY'), b=list('AABBCCDD')))
----> 2 df.groupby('a').apply(lambda x: x['b'][0])
0
X. Liu 27 oct. 2017 a las 22:11

3 respuestas

La mejor respuesta

Recibes un error clave debido a [0]. Si bien no es una descripción perfecta, cuando especifica

df.groupby('a')

Está creando algo así como un iterador de pares (etiqueta, marco de datos) para cada grupo, y no es hasta que llame a apply que alguna función se aplica a cada uno de esos "subtramas". Por ejemplo,

for grp, frame in df.groupby('a'):
    print('Group', grp)
    print(frame)
    print()

Group X
   a  b
0  X  A
2  X  B
4  X  C
6  X  D

Group Y
   a  b
1  Y  A
3  Y  B
5  Y  C
7  Y  D

El uso de [0] intentará indexar por etiqueta, no por ubicación entera, y su DataFrame donde a == Y se indexa con [1, 3, 5, 7]. En otras palabras, estás tratando de hacer:

df2 = df[df.a=='Y']
df2['b'][0]  # Not only is this a key error, it's also chained indexing

Puede resultarle útil: ¿Cómo funciona realmente el método pandas groupby?

La versión de trabajo de su código sería

df.groupby('a').apply(lambda x: x.iloc[0,1])

Pero debería preferir la solución de @ juanpa, que será más rápida aquí.

2
Brad Solomon 27 oct. 2017 a las 19:21

Si te gusta usar apply

df.groupby('a').b.apply(lambda x: x.values.tolist()[0])
Out[952]: 
a
X    A
Y    A
Name: b, dtype: object

O tratar

df.groupby('a').b.first()
Out[960]: 
a
X    A
Y    A
Name: b, dtype: object
0
YOBEN_S 27 oct. 2017 a las 19:38

@BradSolomon explicó la fuente de su error. Sin embargo, creo que lo que realmente quieres es lo siguiente:

In [7]: df.groupby('a')['b'].nth(0)
Out[7]:
a
X    A
Y    A
Name: b, dtype: object
1
juanpa.arrivillaga 27 oct. 2017 a las 19:16