Encuentra el máximo de dos o más columnas con pandas.

Tengo un dataframe con las columnas A , B Necesito crear una columna C tal que para cada registro / fila:

C = max(A, B) .

¿Cómo debo hacer para hacer esto?

Gracias.

Puede obtener el máximo de esta manera:

 >>> import pandas as pd >>> df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]}) >>> df AB 0 1 -2 1 2 8 2 3 1 >>> df[["A", "B"]] AB 0 1 -2 1 2 8 2 3 1 >>> df[["A", "B"]].max(axis=1) 0 1 1 8 2 3 

y entonces:

 >>> df["C"] = df[["A", "B"]].max(axis=1) >>> df ABC 0 1 -2 1 1 2 8 8 2 3 1 3 

Si sabe que “A” y “B” son las únicas columnas, incluso podría salirse con la suya.

 >>> df["C"] = df.max(axis=1) 

Y podría usar .apply(max, axis=1) también, supongo.

La respuesta de @ DSM está perfectamente bien en casi cualquier escenario normal. Pero si usted es el tipo de progtwigdor que quiere ir un poco más allá del nivel de la superficie, puede que le interese saber que es un poco más rápido llamar a las funciones numpy en la matriz de .values subyacentes en lugar de llamar directamente al ) Funciones definidas en los objetos DataFrame / Series.

Por ejemplo, puede usar ndarray.max largo del primer eje.

 # Data borrowed from @DSM's post. df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]}) df AB 0 1 -2 1 2 8 2 3 1 df['C'] = df[['A', 'B']].values.max(1) # Or, assuming "A" and "B" are the only columns, # df['C'] = df.values.max(1) df ABC 0 1 -2 1 1 2 8 8 2 3 1 3 

Tenga en cuenta que si sus datos tienen NaN s, necesitará np.nanmax :

 df['C'] = np.nanmax(df.values, axis=1) df ABC 0 1 -2 1 1 2 8 8 2 3 1 3 

También puedes usar numpy.maximum.reduce . np.maximum es un ufunc (Función Universal) , y cada ufunc tiene una reduce :

 df['C'] = np.maximum.reduce(df['A', 'B']].values, axis=1) # df['C'] = np.maximum.reduce(df[['A', 'B']], axis=1) # df['C'] = np.maximum.reduce(df, axis=1) df ABC 0 1 -2 1 1 2 8 8 2 3 1 3 

Actuación

Medido utilizando el módulo perfplot . El gráfico generado muestra el rendimiento relativo; El eje Y es logarítmico.

 import pandas as pd import perfplot np.random.seed(0) df_ = pd.DataFrame(np.random.randn(5, 1000)) perfplot.show( setup=lambda n: pd.concat([df_] * n, ignore_index=True), kernels=[ lambda df: df.assign(new=df.max(axis=1)), lambda df: df.assign(new=df.values.max(1)), lambda df: df.assign(new=np.nanmax(df.values, axis=1)), lambda df: df.assign(new=np.maximum.reduce(df.values, axis=1)), ], labels=['df.max', 'np.max', 'np.maximum.reduce', 'np.nanmax'], n_range=[2**k for k in range(0, 12)], xlabel='N (* len(df))', logy=True ) 

introduzca la descripción de la imagen aquí

np.maximum.reduce y np.max parecen ser más o menos iguales (para los DataFrames de tamaño más normal), y resultan ser un tono más rápido que DataFrame.max . Me imagino que esta diferencia se mantiene aproximadamente constante y se debe a una sobrecarga interna (alineación de indización, manejo de NaN, etc.).