pandas dataframe groupby y obtener nth fila

Tengo un dataframe de pandas como siguiente.

df = pd.DataFrame([[1.1, 1.1, 1.1, 2.6, 2.5, 3.4,2.6,2.6,3.4,3.4,2.6,1.1,1.1,3.3], list('AAABBBBABCBDDD'), [1.1, 1.7, 2.5, 2.6, 3.3, 3.8,4.0,4.2,4.3,4.5,4.6,4.7,4.7,4.8], ['x/y/z','x/y','x/y/z/n','x/u','x','x/u/v','x/y/z','x','x/u/v/b','-','x/y','x/y/z','x','x/u/v/w'],['1','3','3','2','4','2','5','3','6','3','5','1','1','1'],['200','400','404','200','200','404','200','404','500','200','500','200','200','400']]).T df.columns = ['col1','col2','col3','col4','ID','col5'] 

Quiero agrupar esto por “ID” y obtener la segunda fila de cada grupo. Más tarde necesitaré obtener tercero y cuarto también. Solo explícame cómo obtener solo la segunda fila de cada grupo.

Intenté seguir lo que da primero y segundo.

 df.groupby('ID').head(2) 

En vez de eso necesito conseguir solo la segunda fila. Dado que las ID 4 y 6 no tienen segundas filas, es necesario ignorarlas.

  col1 col2 col3 col4 ID col5 ID 1 0 1.1 A 1.1 x/y/z 1 200 11 1.1 D 4.7 x/y/z 1 200 2 3 2.6 B 2.6 x/u 2 200 5 3.4 B 3.8 x/u/v 2 404 3 1 1.1 A 1.7 x/y 3 400 2 1.1 A 2.5 x/y/z/n 3 404 4 4 2.5 B 3.3 x 4 200 5 6 2.6 B 4 x/y/z 5 200 10 2.6 B 4.6 x/y 5 500 6 8 3.4 B 4.3 x/u/v/b 6 500 

Creo que el noveno método debe hacer precisamente eso:

 In [11]: g.nth(1).dropna() Out[11]: col1 col2 col3 col4 col5 ID 1 1.1 D 4.7 x/y/z 200 2 3.4 B 3.8 x/u/v 404 3 1.1 A 2.5 x/y/z/n 404 5 2.6 B 4.6 x/y 500 

En 0.13 otra forma de hacer esto es usar cumcount:

 df[g.cumcount() == n - 1] 

… lo cual es significativamente más rápido.

 In [21]: %timeit g.nth(1).dropna() 100 loops, best of 3: 11.3 ms per loop In [22]: %timeit df[g.cumcount() == 1] 1000 loops, best of 3: 286 µs per loop 

Si utiliza apply en el groupby, la función que pasa se llama en cada grupo, se pasa como un DataFrame. Así que puedes hacer:

 df.groupby('ID').apply(lambda t: t.iloc[1]) 

Sin embargo, esto generará un error si el grupo no tiene al menos dos filas. Si desea excluir grupos con menos de dos filas, podría ser más complicado. No tengo conocimiento de una manera de excluir el resultado de apply solo para ciertos grupos. Puede intentar filtrar primero la lista de grupos eliminando grupos pequeños, o devolver un DataFrame con una fila de datos completos y hacer un dropna en el resultado.