seleccione la N más grande de una columna de cada grupo por grupo usando pandas

Mi df:

{'city1': {0: 'Chicago', 1: 'Chicago', 2: 'Chicago', 3: 'Chicago', 4: 'Miami', 5: 'Houston', 6: 'Austin'}, 'city2': {0: 'Toronto', 1: 'Detroit', 2: 'St.Louis', 3: 'Miami', 4: 'Dallas', 5: 'Dallas', 6: 'Dallas'}, 'p234_r_c': {0: 5.0, 1: 4.0, 2: 2.0, 3: 0.5, 4: 1.0, 5: 4.0, 6: 3.0}, 'plant1_type': {0: 'COMBCYCL', 1: 'COMBCYCL', 2: 'NUKE', 3: 'COAL', 4: 'NUKE', 5: 'COMBCYCL', 6: 'COAL'}, 'plant2_type': {0: 'COAL', 1: 'COAL', 2: 'COMBCYCL', 3: 'COMBCYCL', 4: 'COAL', 5: 'NUKE', 6: 'NUKE'}} 

Quiero hacer 2 operaciones grupales y tomar el 1 más grande de cada grupo usando la columna p234_r_c .

1er grupoby = ['plant1_type', 'plant2_type', 'city1']

2do groupby = ['plant1_type', 'plant2_type', 'city2']

Como tal hago lo siguiente:

 df.groupby(['plant1_type','plant2_type','city1'])['p234_r_c'].\ nlargest(1).reset_index() plant1_type plant2_type city1 level_3 p234_r_c 0 COAL COMBCYCL Chicago 3 0.5 1 COAL NUKE Austin 6 3.0 2 COMBCYCL COAL Chicago 0 5.0 3 COMBCYCL NUKE Houston 5 4.0 4 NUKE COAL Miami 4 1.0 5 NUKE COMBCYCL Chicago 2 2.0 

El resultado del primer grupo tiene sentido. Sin embargo, estoy confundido por el resultado del segundo grupo por:

 df.groupby(['plant1_type','plant2_type','city2'])['p234_r_c'].\ nlargest(1).reset_index() index p234_r_c 0 0 5.0 1 1 4.0 2 2 2.0 3 3 0.5 4 4 1.0 5 5 4.0 6 6 3.0 

¿Qué pasó con las columnas plant1_type , plant2_type y city2 en el resultado? ¿No deberían aparecer en el resultado exactamente como plant1_type , plant2_type y city1 aparecieron en el resultado del primer grupo?

He añadido un problema aquí

Teoría:

Cuando los resultados de un groupby en un pd.Series devuelven los mismos valores de pd.Series , se devuelve el índice original.

Ejemplo hervido

 df = pd.DataFrame(dict(A=[0, 1, 2, 3])) # returns results identical to df.A print(df.groupby(df.A // 2).A.nsmallest(2)) # returns results out of order print(df.groupby(df.A // 2).A.nlargest(2)) 0 0 1 1 2 2 3 3 Name: A, dtype: int64 A 0 1 1 0 0 1 3 3 2 2 Name: A, dtype: int64 

Yo diría que desea que estos devuelvan el mismo índice consistente.

Esta es la consecuencia más grave de esto:

 # most egregious # this will be randomly different print(df.groupby(df.A // 2).A.apply(pd.Series.sample, n=2)) 

devuelve esto en una ejecución

 A 0 1 1 0 0 1 2 2 3 3 Name: A, dtype: int64 

Y esto en otro.

 0 0 1 1 2 2 3 3 Name: A, dtype: int64 

Por supuesto, esto nunca tiene un problema porque es imposible devolver los mismos valores que el original

 print(df.groupby(df.A // 2).A.apply(pd.Series.sample, n=1)) A 0 0 0 1 2 2 Name: A, dtype: int64 

Trabajar alrededor
set_index

 cols = ['plant1_type','plant2_type','city2'] df.set_index(cols).groupby(level=cols)['p234_r_c'].\ nlargest(1).reset_index() plant1_type plant2_type city2 p234_r_c 0 COMBCYCL COAL Toronto 5.0 1 COMBCYCL COAL Detroit 4.0 2 NUKE COMBCYCL St.Louis 2.0 3 COAL COMBCYCL Miami 0.5 4 NUKE COAL Dallas 1.0 5 COMBCYCL NUKE Dallas 4.0 6 COAL NUKE Dallas 3.0