Tìm hàng trong đó các giá trị cho cột là tối đa trong DataFrame của gấu trúc


208

Làm cách nào tôi có thể tìm thấy hàng mà giá trị của một cột cụ thể là tối đa ?

df.max() sẽ cho tôi giá trị tối đa cho mỗi cột, tôi không biết cách lấy hàng tương ứng.


Có thể nhận được 2 giá trị hàng đầu? thay vì chỉ tối đa?
AsheKetchum

5
Bạn có thể sử dụng sort_valuesvà lấy chỉ mục:df.sort_values('col', ascending=False)[:2].index
lazy1

2
lazy1: tránh sắp xếp một cách không cần thiết toàn bộ một chuỗi vì trung bình là O (N logN), trong khi tìm max / idxmax chỉ là O (N).
smci

Câu trả lời:


240

Sử dụng idxmaxchức năng gấu trúc . Thật đơn giản:

>>> import pandas
>>> import numpy as np
>>> df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
>>> df
          A         B         C
0  1.232853 -1.979459 -0.573626
1  0.140767  0.394940  1.068890
2  0.742023  1.343977 -0.579745
3  2.125299 -0.649328 -0.211692
4 -0.187253  1.908618 -1.862934
>>> df['A'].argmax()
3
>>> df['B'].argmax()
4
>>> df['C'].argmax()
1
  • Ngoài ra, bạn cũng có thể sử dụng numpy.argmax, chẳng hạn như numpy.argmax(df['A'])- nó cung cấp điều tương tự, và xuất hiện ít nhất là nhanh như idxmaxtrong các quan sát chữ thảo.

  • idxmax() trả về các chỉ số nhãn, không phải số nguyên.

    • Ví dụ ': nếu bạn có các giá trị chuỗi làm nhãn chỉ mục của mình, như các hàng' a 'đến' e ', bạn có thể muốn biết rằng tối đa xảy ra ở hàng 4 (không phải hàng' d ').
    • nếu bạn muốn vị trí số nguyên của nhãn đó trong đó Indexbạn phải lấy nó bằng tay (điều này có thể khó khăn khi các nhãn hàng trùng lặp được cho phép).

THÔNG BÁO LỊCH SỬ:

  • idxmax()được sử dụng để được gọi argmax()trước 0.11
  • argmax không được chấp nhận trước 1.0.0 và bị xóa hoàn toàn trong 1.0.0
  • trở lại như của Pandas 0.16, argmaxđược sử dụng để tồn tại và thực hiện chức năng tương tự (mặc dù dường như chạy chậm hơn idxmax).
    • argmaxHàm trả về vị trí số nguyên trong chỉ mục của vị trí hàng của phần tử tối đa.
    • gấu trúc chuyển sang sử dụng nhãn hàng thay vì chỉ số nguyên. Các chỉ số nguyên vị trí được sử dụng rất phổ biến, phổ biến hơn các nhãn, đặc biệt là trong các ứng dụng có nhãn hàng trùng lặp là phổ biến.

Ví dụ: xem xét đồ chơi này DataFramevới nhãn hàng trùng lặp:

In [19]: dfrm
Out[19]: 
          A         B         C
a  0.143693  0.653810  0.586007
b  0.623582  0.312903  0.919076
c  0.165438  0.889809  0.000967
d  0.308245  0.787776  0.571195
e  0.870068  0.935626  0.606911
f  0.037602  0.855193  0.728495
g  0.605366  0.338105  0.696460
h  0.000000  0.090814  0.963927
i  0.688343  0.188468  0.352213
i  0.879000  0.105039  0.900260

In [20]: dfrm['A'].idxmax()
Out[20]: 'i'

In [21]: dfrm.iloc[dfrm['A'].idxmax()]  # .ix instead of .iloc in older versions of pandas
Out[21]: 
          A         B         C
i  0.688343  0.188468  0.352213
i  0.879000  0.105039  0.900260

Vì vậy, ở đây việc sử dụng ngây thơ idxmaxlà không đủ, trong khi hình thức cũ argmaxsẽ cung cấp chính xác vị trí vị trí của hàng tối đa (trong trường hợp này là vị trí 9).

Đây chính xác là một trong những loại hành vi dễ bị lỗi trong các ngôn ngữ được gõ động khiến cho việc này trở nên rất đáng tiếc và đáng để đánh bại một con ngựa chết. Nếu bạn đang viết mã hệ thống và hệ thống của bạn đột nhiên được sử dụng trên một số bộ dữ liệu không được làm sạch đúng cách trước khi tham gia, thì rất dễ kết thúc với nhãn hàng trùng lặp, đặc biệt là nhãn chuỗi như mã định danh CUSIP hoặc SEDOL cho tài sản tài chính. Bạn không thể dễ dàng sử dụng hệ thống loại để giúp bạn và bạn không thể thực thi tính duy nhất trên chỉ mục mà không chạy vào dữ liệu bị thiếu bất ngờ.

Vì vậy, bạn sẽ rời đi với hy vọng rằng các bài kiểm tra đơn vị của bạn bao gồm tất cả mọi thứ (họ không, hoặc nhiều khả năng không ai viết bất kỳ bài kiểm tra nào) - nếu không (rất có thể) bạn chỉ còn chờ xem liệu bạn có tình cờ gặp phải điều này không lỗi khi chạy, trong trường hợp này bạn có thể phải đi thả nhiều giờ giá trị của công việc từ cơ sở dữ liệu bạn đã xuất ra kết quả, đập đầu mình vào tường trong IPython cố gắng tự tạo lại vấn đề, cuối cùng tìm ra rằng đó là vì idxmaxcó thể chỉ báo cáo nhãn của hàng tối đa và sau đó thất vọng vì không có chức năng tiêu chuẩn nào tự động nhận vị trí của hàng tối đa cho bạn, tự mình thực hiện một lỗi, chỉnh sửa mã và cầu nguyện bạn không gặp lại vấn đề.


13
Dựa trên nhận xét thứ hai đến cuối cùng ở đó, có vẻ như argminargmaxsẽ vẫn là một phần của DataFramevà sự khác biệt chỉ là dù bạn muốn chỉ mục hay nhãn hiệu. idxmaxsẽ cung cấp cho bạn nhãn của vị trí xảy ra tối đa. argmaxsẽ cung cấp cho bạn số nguyên chỉ mục chính nó.
ely

4
Thông tin được cung cấp để giải thích sự khác biệt giữa argmaxidxmax, và làm thế nào để tránh các lỗi có chỉ số trùng lặp là tuyệt vời! Tôi đã không nhận thấy điều đó cho đến khi tôi đọc bình luận của bạn trong câu trả lời khác. Cảm ơn!
tupan

Liên quan đến việc sử dụng mà bạn muốn thực hiện, Pandas 0.24.1 chỉ ra những điều sau: 'hành vi của argmaxsẽ được sửa chữa để trả về mức tối đa theo vị trí trong tương lai. Hiện tại, sử dụng series.values.argmaxhoặc np.argmax(np.array(values))để có được vị trí của hàng tối đa. '
Sam

1
tương tự, .ixphương thức của ví dụ thứ hai đã được đổi tên thành.iloc
Ma0

nếu cột của bạn chỉ chứa các giá trị nan, điều này sẽ dẫn đến TypeError
Max Segal

77

Bạn cũng có thể thử idxmax:

In [5]: df = pandas.DataFrame(np.random.randn(10,3),columns=['A','B','C'])

In [6]: df
Out[6]: 
          A         B         C
0  2.001289  0.482561  1.579985
1 -0.991646 -0.387835  1.320236
2  0.143826 -1.096889  1.486508
3 -0.193056 -0.499020  1.536540
4 -2.083647 -3.074591  0.175772
5 -0.186138 -1.949731  0.287432
6 -0.480790 -1.771560 -0.930234
7  0.227383 -0.278253  2.102004
8 -0.002592  1.434192 -1.624915
9  0.404911 -2.167599 -0.452900

In [7]: df.idxmax()
Out[7]: 
A    0
B    8
C    7

ví dụ

In [8]: df.loc[df['A'].idxmax()]
Out[8]: 
A    2.001289
B    0.482561
C    1.579985

Cảm ơn Wes. Tài liệu cho idxmax () tại đây: pandas.pydata.org/pandas-docs/dev/generated/ Kẻ
Sẽ

df.ix[df['A'].idxmax()].valuesđể lấy mảng tôi muốn. vẫn hoạt động.
Yojimbo

2
Lưu ý rằng bạn cần cẩn thận khi cố gắng sử dụng đầu ra của idxmaxbộ nạp vào ixhoặc loclàm phương tiện để cắt phụ dữ liệu và / hoặc để có được vị trí vị trí của hàng tối đa. Bởi vì bạn có thể có các bản sao trong Index- xem bản cập nhật cho câu trả lời của tôi để biết ví dụ.
ely

25

Cả hai câu trả lời trên sẽ chỉ trả về một chỉ mục nếu có nhiều hàng lấy giá trị tối đa. Nếu bạn muốn tất cả các hàng, dường như không có chức năng. Nhưng nó không khó để làm. Dưới đây là một ví dụ cho Series; điều tương tự có thể được thực hiện cho DataFrame:

In [1]: from pandas import Series, DataFrame

In [2]: s=Series([2,4,4,3],index=['a','b','c','d'])

In [3]: s.idxmax()
Out[3]: 'b'

In [4]: s[s==s.max()]
Out[4]: 
b    4
c    4
dtype: int64

10
Cảm ơn! phiên bản cho DataFrame:df[df['A'] == df['A'].max()]
Dennis Golomazov

Đây là câu trả lời thực sự chính xác (phiên bản DataFrame).
gents

12
df.iloc[df['columnX'].argmax()]

argmax()sẽ cung cấp chỉ số tương ứng với giá trị tối đa cho cộtX. iloccó thể được sử dụng để lấy hàng của DataFrame df cho chỉ mục này.


4

Giải pháp ".argmax ()" trực tiếp không phù hợp với tôi.

Ví dụ trước được cung cấp bởi @ely

>>> import pandas
>>> import numpy as np
>>> df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
>>> df
      A         B         C
0  1.232853 -1.979459 -0.573626
1  0.140767  0.394940  1.068890
2  0.742023  1.343977 -0.579745
3  2.125299 -0.649328 -0.211692
4 -0.187253  1.908618 -1.862934
>>> df['A'].argmax()
3
>>> df['B'].argmax()
4
>>> df['C'].argmax()
1

trả về thông báo sau:

FutureWarning: 'argmax' is deprecated, use 'idxmax' instead. The behavior of 'argmax' 
will be corrected to return the positional maximum in the future.
Use 'series.values.argmax' to get the position of the maximum now.

Vì vậy, giải pháp của tôi là:

df['A'].values.argmax()

2
mx.iloc[0].idxmax()

Một dòng mã này sẽ cung cấp cho bạn cách tìm giá trị tối đa từ một hàng trong khung dữ liệu, đây mxlà khung dữ liệu và iloc[0]cho biết chỉ số 0.


1

Các idmaxcủa DataFrame trả về chỉ số nhãn của hàng với giá trị lớn nhất và hành vi của argmaxphụ thuộc vào phiên bản của pandas(ngay bây giờ nó trả về một cảnh báo). Nếu bạn muốn sử dụng chỉ mục vị trí , bạn có thể làm như sau:

max_row = df['A'].values.argmax()

hoặc là

import numpy as np
max_row = np.argmax(df['A'].values)

Lưu ý rằng nếu bạn sử dụng np.argmax(df['A'])hành vi giống như df['A'].argmax().

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.