Tìm tối đa của hai hoặc nhiều cột có gấu trúc


100

Tôi có một dataframe với các cột A, B. Tôi cần tạo một cột Csao 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:


190

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.


1
.apply(max, axis=1)chậm hơn nhiều so với.max(axis=1)
RajeshM

28

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 .valuescho <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ó NaNs, 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.maximumlà một ufunc (Hàm phổ quát)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

nhập mô tả hình ảnh ở đây

np.maximum.reducevà có np.maxvẻ 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)

Lỗi chính tả nhỏ: "df ['C'] = np.maximum.reduce (df ['A', 'B']]. Giá trị, axis = 1)" phải là "df ['C'] = np.maximum. giảm (df [['A', 'B']]. giá trị, trục = 1) "
Velizar VESSELINOV
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.