Tôi có một dataframe với các cột A
, B
. Tôi cần tạo một cột C
sao cho mọi bản ghi / hàng:
C = max(A, B)
.
Tôi nên làm như thế nào về việc này?
Câu trả lời:
Bạn có thể nhận được tối đa như thế này:
>>> 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
và vì thế:
>>> df["C"] = df[["A", "B"]].max(axis=1)
>>> df
A B C
0 1 -2 1
1 2 8 8
2 3 1 3
Nếu bạn biết rằng "A" và "B" là các cột duy nhất, bạn thậm chí có thể bỏ qua
>>> df["C"] = df.max(axis=1)
Và bạn cũng có thể sử dụng .apply(max, axis=1)
, tôi đoán vậy.
Câu trả lời của @ DSM là hoàn toàn ổn trong hầu hết mọi trường hợp bình thường. Nhưng nếu bạn là kiểu lập trình viên muốn đi sâu hơn một chút so với mức bề mặt, bạn có thể muốn biết rằng sẽ nhanh hơn một chút nếu gọi các hàm numpy trên mảng bên dưới .to_numpy()
(hoặc .values
cho <0,24) thay vì trực tiếp gọi các hàm (được mạng hóa) được xác định trên các đối tượng DataFrame / Series.
Ví dụ, bạn có thể sử dụng ndarray.max()
dọc theo trục đầu tiên.
# 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
Nếu dữ liệu của bạn có NaN
s, bạn sẽ cần 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
Bạn cũng có thể sử dụng numpy.maximum.reduce
. numpy.maximum
là một ufunc (Hàm phổ quát) và mọi ufunc đều có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
và có np.max
vẻ giống nhau nhiều hơn hoặc ít hơn (đối với hầu hết các DataFrame có kích thước bình thường) —và tình cờ nhanh hơn DataFrame.max
. Tôi tưởng tượng sự khác biệt này gần như không đổi và là do chi phí nội bộ (liên kết lập chỉ mục, xử lý NaN, v.v.).
Biểu đồ được tạo bằng cách sử dụng perfplot . Mã điểm chuẩn, để tham khảo:
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)
chậm hơn nhiều so với.max(axis=1)