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