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

101

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

C = max(A, B).

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

Navneet
источник

Ответы:

191

Получить максимум можно так:

>>> 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)Думаю, ты тоже можешь использовать .

DSM
источник
1
.apply(max, axis=1)намного медленнее, чем.max(axis=1)
RajeshM
28

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

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

# 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 

Если в ваших данных есть NaNs, вам понадобятся 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

введите описание изображения здесь

np.maximum.reduceи np.maxкажутся более или менее одинаковыми (для большинства DataFrames нормального размера) - и оказываются на оттенок быстрее, чем 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)
cs95
источник
Небольшая опечатка: «df ['C'] = np.maximum.reduce (df ['A', 'B']]. Values, axis = 1)» должно быть «df ['C'] = np.maximum. reduce (df [['A', 'B']]. values, axis = 1) »
Велизар ВЕССЕЛИНОВ