У меня есть dataframe с колоннами A
, B
. Мне нужно создать столбецC
, чтобы для каждой записи / строки:
C = max(A, B)
.
Как мне это сделать?
Ответы:
Получить максимум можно так:
>>> 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 отлично подходит практически для любого нормального сценария. Но если вы из тех программистов, которые хотят пойти немного глубже, чем поверхностный уровень, вам может быть интересно узнать, что немного быстрее вызывать функции 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
Если в ваших данных есть NaN
s, вам понадобятся 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)
.apply(max, axis=1)
намного медленнее, чем.max(axis=1)