Подтвердить что ты не робот

Найти максимум двух или более столбцов с пандами

У меня есть dataframe с столбцами A, B. Мне нужно создать столбец C такой, что для каждой записи/строки:

C = max(A, B).

Как мне это сделать?

Спасибо.

4b9b3361

Ответ 1

Вы можете получить максимум, как это:

>>> 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

и так:

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

Если вы знаете, что "A" и "B" являются единственными столбцами, вы даже можете уйти с помощью

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

И вы могли бы использовать .apply(max, axis=1) тоже, я думаю.

Ответ 2

Ответ @DSM прекрасно подходит практически для любого обычного сценария. Но если вы тот тип программиста, который хочет пойти немного глубже, чем поверхностный уровень, вам может быть интересно узнать, что немного быстрее вызывать numy-функции для базовых .to_numpy() (или .values для < 0.24) вместо непосредственного вызова (цитонизированных) функций, определенных в объектах DataFrame/Series.

Например, вы можете использовать ndarray.max() вдоль первой оси.

# Data borrowed from @DSM 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 

Обратите внимание, что если ваши данные имеют NaN, вам понадобится 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 

Вы также можете использовать numpy.maximum.reduce. numpy.maximum - это ufunc (универсальная функция), и каждый ufunc имеет 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

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3

enter image description here

np.maximum.reduce и np.max кажутся более или менее одинаковыми (для большинства кадров данных нормального размера) и оказываются на тень быстрее, чем DataFrame.max. Я полагаю, что это различие примерно остается постоянным и связано с внутренними издержками (выравнивание индекса, обработка NaN и т.д.).

График был сгенерирован с использованием perfplot. Код для сравнения, для справки:

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)