Estoy tratando de eliminar duplicados consecutivos de la columna X mientras mantengo la entrada con el valor máximo basado en la columna Y, desafortunadamente sin éxito. El marco de datos es el siguiente:
| idx | X | Y |
|---|---|---|
| 0 | UN | 3 |
| 1 | B | 2 |
| 2 | UN | 7 |
| 3 | UN | 10 |
| 4 | B | 1 |
| 5 | C | 4 |
| 6 | UN | 3 |
| 7 | UN | 3 |
Lo que quiero lograr es:
| idx | X | Y |
|---|---|---|
| 0 | UN | 3 |
| 1 | B | 2 |
| 3 | UN | 10 |
| 4 | B | 1 |
| 5 | C | 4 |
| 7 | UN | 3 |
La mayoría de las soluciones que encontré simplemente eliminan los duplicados sin tener en cuenta ningún patrón repetitivo.
Tenga en cuenta que los duplicados pueden tener el mismo valor.
Debe aplicar itertools-style-groupby y luego mantener las filas donde Y es maximal .
>>> df idx XY 0 0 A 3 1 1 B 2 2 2 A 7 3 3 A 10 4 4 B 1 5 5 C 4 6 6 A 3 7 7 A 5 >>> y_max = df.groupby(df['X'].ne(df['X'].shift()).cumsum())['Y'].transform('max') >>> df[df['Y'] == y_max] idx XY 0 0 A 3 1 1 B 2 3 3 A 10 4 4 B 1 5 5 C 4 7 7 A 5editar:
La solución inicial tenía un error y solo producía la columna idx correcta por accidente.
editar 2:
Si solo desea mantener una fila por grupo, puede usar
>>> y_idxmax = df.groupby(df['X'].ne(df['X'].shift()).cumsum())['Y'].idxmax() >>> df.loc[y_idxmax] idx XY 0 0 A 3 1 1 B 2 3 3 A 10 4 4 B 1 5 5 C 4 7 7 A 5El crédito va a Ch3steR por este.
O preferiría simplemente especificar los grupos en los parámetros groupby :
df.groupby(df['X'].ne(df['X'].shift()).cumsum(), as_index=False).max()O:
df.groupby(df['X'].ne(df['X'].shift()).cumsum()).max().reset_index(drop=True)Ambas salidas:
idx XY 0 0 A 3 1 1 B 2 2 3 A 10 3 4 B 1 4 5 C 4 5 7 A 5Cree una columna que acumule consecutivos en un grupo
df['temp']=(~(df['X']==df['X'].shift())|(df['X'].shift(-1)==df['X'])).cumsum()groupby el grupo de consecutivos y filtrar donde los valores de Y son iguales al máximo en cada grupo. Suelta la columna temporal
df[df.groupby('temp')['Y'].transform(lambda x:(x==x.max()))].drop(columns=['temp'])Una forma más ordenada es no crear una columna sino guardar los grupos de consecutivos en una variable y agruparlos por la variable de la siguiente manera
s=(~(df['X']==df['X'].shift())|(df['X'].shift(-1)==df['X'])).cumsum() print(df[df.groupby(s)['Y'].transform(lambda x:(x==x.max()))]) idx XY 0 0 A 3 1 1 B 2 3 3 A 10 4 4 B 1 5 5 C 4 7 7 A 5