У мене є 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
Якщо ви знаєте, що "А" та "В" - це єдині стовпці, то навіть можна піти
>>> 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
здаються більш-менш однаковими (для більшості кадрів даних нормального розміру) - і трапляються на відтінок швидше, ніж DataFrame.max
. Я думаю, ця різниця приблизно залишається постійною і пов'язана з внутрішніми накладними витратами (вирівнювання індексування, обробка NaNs тощо).
Графік був сформований за допомогою 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)