Tengo una df como esta:

 A    |  B     |  C  | D
14    |  5     | 10  | 5
 4    |  7     | 15  | 6
100   | 220    |  6  | 7

Para cada fila en la columna A, B, C, quiero encontrar el valor máximo y restar la columna D y reemplazarla.

Resultado esperado:

 A   |  B   |  C  |  D
 9   |  5   | 10  |  5
 4   |  7   |  9  |  6
100  | 213  |  6  |  7

Entonces, para la primera fila, seleccionaría 14 (el máximo de 14,5,10), le restaría la columna D (14-5 = 9) y reemplazaría el resultado (reemplazaría el valor inicial 14 con 9)

Sé cómo encontrar el valor máximo de A, B, C y, a partir de él, restar D, pero estoy atascado en la parte de reemplazo.

Pensé en poner el resultado en otra columna llamada E, y luego encontrar nuevamente el máximo de A, B, C y reemplazarlo con la columna E, pero eso no tendría sentido ya que estaría intentando asignar un valor a una llamada de función. ¿Existe alguna otra opción para hacer esto?

#Exmaple df
list_columns = ['A', 'B', 'C','D']
list_data = [ [14, 5, 10,5],[4, 7, 15,6],[100, 220, 6,7]]
df= pd.DataFrame(columns=list_columns, data=list_data)

#Calculate the max and subctract 
df['e'] = df[['A', 'B']].max(axis=1) - df['D']

#To replace, maybe something like this. But this line makes no sense since it's backwards
df[['A', 'B','C']].max(axis=1) = df['D']
1
chris_b 22 ene. 2021 a las 16:59

1 respuesta

La mejor respuesta

Utilice DataFrame.mask para reemplazar solo el valor máximo que coincide con la comparación de todos los valores de las columnas filtradas con los máximos:

cols = ['A', 'B', 'C']
s =  df[cols].max(axis=1)
df[cols] = df[cols].mask(df[cols].eq(s, axis=0), s - df['D'], axis=0)
print (df)
     A    B   C  D
0    9    5  10  5
1    4    7   9  6
2  100  213   6  7
1
jezrael 22 ene. 2021 a las 14:04