Tengo una trama de datos con columnas A
, B
. Necesito crear una columna de C
modo que para cada registro / fila:
C = max(A, B)
.
¿Cómo debo hacer esto?
Respuestas:
Puede obtener el máximo de esta manera:
>>> import pandas as pd
>>> df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
>>> df
A B
0 1 -2
1 2 8
2 3 1
>>> df[["A", "B"]]
A B
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
A B C
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 a ti .apply(max, axis=1)
también te vendría bien , supongo.
La respuesta de @ DSM está perfectamente bien en casi cualquier escenario normal. Pero si usted es el tipo de programador que quiere ir un poco más profundo que el nivel de la superficie, es posible que le interese saber que es un poco más rápido llamar a funciones numpy en la matriz subyacente .to_numpy()
(o .values
para <0.24) en lugar de directamente llamando a las funciones (cythonized) definidas en los objetos DataFrame / Series.
Por ejemplo, puede utilizar a lo ndarray.max()
largo del primer eje.
# Data borrowed from @DSM's post.
df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
df
A B
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
A B C
0 1 -2 1
1 2 8 8
2 3 1 3
Si sus datos tienen NaN
s, necesitará numpy.nanmax
:
df['C'] = np.nanmax(df.values, axis=1)
df
A B C
0 1 -2 1
1 2 8 8
2 3 1 3
También puede utilizar numpy.maximum.reduce
. numpy.maximum
es una ufunc (función universal) , y cada ufunc tiene unreduce
:
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
A B C
0 1 -2 1
1 2 8 8
2 3 1 3
np.maximum.reduce
y np.max
parecen ser más o menos iguales (para la mayoría de DataFrames de tamaño normal), y resultan ser un poco más rápidos que DataFrame.max
. Me imagino que esta diferencia permanece aproximadamente constante y se debe a la sobrecarga interna (alineación de indexación, manejo de NaN, etc.).
El gráfico se generó usando perfplot . Código de evaluación comparativa, como referencia:
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, 15)],
xlabel='N (* len(df))',
logx=True,
logy=True)
.apply(max, axis=1)
es mucho más lento que.max(axis=1)