ค้นหาแถวที่มีค่าสำหรับคอลัมน์สูงสุดใน pandas DataFrame


208

ฉันจะค้นหาแถวที่ค่าของคอลัมน์ใดคอลัมน์หนึ่งมีค่าสูงสุดได้อย่างไร

df.max() จะให้ค่าสูงสุดแก่ฉันสำหรับแต่ละคอลัมน์ฉันไม่ทราบวิธีรับแถวที่เกี่ยวข้อง


เป็นไปได้หรือไม่ที่จะได้รับ 2 ค่าสูงสุด แทนค่าสูงสุดเท่านั้น
AsheKetchum

5
คุณสามารถใช้sort_valuesและรับดัชนี:df.sort_values('col', ascending=False)[:2].index
lazy1

2
lazy1: หลีกเลี่ยงการเรียงลำดับทั้งชุดโดยไม่จำเป็นเนื่องจากค่าเฉลี่ย O (N logN) ในขณะที่การค้นหา max / idxmax เป็นเพียง O (N)
smci

คำตอบ:


240

ใช้idxmaxฟังก์ชั่นแพนด้า มันตรงไปตรงมา:

>>> 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
  • หรือคุณอาจใช้numpy.argmaxเช่นnumpy.argmax(df['A'])- มันให้สิ่งเดียวกันและปรากฏอย่างน้อยก็เร็วidxmaxในการสังเกตคร่าวๆ

  • idxmax() ส่งกลับป้ายกำกับดัชนีไม่ใช่จำนวนเต็ม

    • ตัวอย่าง ': หากคุณมีค่าสตริงเป็นป้ายกำกับดัชนีของคุณเช่นแถว' a 'ถึง' e 'คุณอาจต้องการทราบว่าค่าสูงสุดเกิดขึ้นในแถว 4 (ไม่ใช่แถว' d ')
    • หากคุณต้องการตำแหน่งจำนวนเต็มของป้ายกำกับภายในIndexคุณจะต้องได้รับด้วยตนเอง (ซึ่งอาจเป็นเรื่องยุ่งยากในขณะนี้ที่อนุญาตป้ายกำกับแถวที่ซ้ำกัน)

บันทึกประวัติศาสตร์:

  • idxmax()เคยถูกเรียกมาargmax()ก่อน 0.11
  • argmax ถูกเลิกใช้ก่อนหน้า 1.0.0 และถูกลบทั้งหมดใน 1.0.0
  • ด้านหลังของ Pandas 0.16 argmaxเคยมีอยู่แล้วและทำหน้าที่เดียวกัน (แต่ดูเหมือนว่าจะทำงานช้ากว่าidxmax)
    • argmaxฟังก์ชันส่งคืนตำแหน่งจำนวนเต็มภายในดัชนีของตำแหน่งแถวขององค์ประกอบสูงสุด
    • แพนด้าย้ายไปใช้ป้ายกำกับแถวแทนดัชนีจำนวนเต็ม ดัชนีเลขจำนวนเต็มตำแหน่งเคยเป็นเรื่องธรรมดามากและพบได้บ่อยกว่าป้ายกำกับโดยเฉพาะในแอปพลิเคชันที่มีป้ายกำกับแถวซ้ำกัน

ตัวอย่างเช่นพิจารณาของเล่นนี้ DataFrameด้วยป้ายกำกับแถวที่ซ้ำกัน:

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

ดังนั้นที่นี่การใช้งานที่ไร้เดียงสาของidxmaxไม่เพียงพอในขณะที่รูปแบบเก่าของargmaxจะให้อย่างถูกต้องตำแหน่งของแถวสูงสุด (ในกรณีนี้คือตำแหน่งที่ 9)

นี่เป็นหนึ่งในพฤติกรรมที่น่ารังเกียจเหล่านั้นในภาษาที่พิมพ์แบบไดนามิกที่ทำให้สิ่งนี้โชคร้ายและคุ้มค่าที่จะเอาชนะม้าที่ตายแล้ว หากคุณกำลังเขียนรหัสระบบและระบบของคุณจะถูกนำไปใช้กับชุดข้อมูลบางอย่างที่ไม่ได้รับการทำความสะอาดอย่างถูกต้องก่อนที่จะเข้าร่วมมันเป็นเรื่องง่ายมากที่จะจบลงด้วยการติดป้ายแถวซ้ำกันโดยเฉพาะอย่างยิ่ง คุณไม่สามารถใช้ระบบประเภทเพื่อช่วยคุณได้อย่างง่ายดายและคุณอาจไม่สามารถบังคับใช้ดัชนีเฉพาะได้โดยไม่ต้องใช้ข้อมูลที่ไม่คาดคิด

ดังนั้นคุณจึงเหลือด้วยความหวังว่าการทดสอบหน่วยของคุณจะครอบคลุมทุกอย่าง (พวกเขาไม่ได้หรือไม่มีใครเขียนการทดสอบใด ๆ ) - มิฉะนั้น (เป็นไปได้มากที่สุด) ที่คุณเพิ่งจะรอดูว่าคุณบังเอิญเจอสิ่งนี้หรือไม่ ข้อผิดพลาดที่รันไทม์ซึ่งในกรณีนี้คุณอาจจะต้องไปวางมูลค่าหลายชั่วโมงของการทำงานจากฐานข้อมูลที่คุณ outputting ผลปังหัวของคุณกับผนังใน IPython พยายามด้วยตนเองทำให้เกิดปัญหาในที่สุดก็หาว่ามันเป็นเพราะidxmaxสามารถเท่านั้นรายงานป้ายกำกับของแถวสูงสุดแล้วรู้สึกผิดหวังที่ไม่มีฟังก์ชั่นมาตรฐานรับตำแหน่งของแถวสูงสุดโดยอัตโนมัติเขียนการใช้งานด้วยตัวเองการแก้ไขโค้ดและการสวดอ้อนวอนคุณจะไม่พบปัญหาอีก


13
จากความคิดเห็นที่สองถึงครั้งสุดท้ายดูเหมือนว่าargminและargmaxจะยังคงเป็นส่วนหนึ่งDataFrameและความแตกต่างก็คือว่าคุณต้องการดัชนีหรือป้ายกำกับ idxmaxจะให้ป้ายกำกับของสถานที่ที่มีค่าสูงสุดเกิดขึ้น argmaxจะทำให้คุณเป็นจำนวนเต็มดัชนี
ely

4
ข้อมูลที่ให้เพื่ออธิบายความแตกต่างระหว่างargmaxและidxmaxและวิธีการหลีกเลี่ยงข้อบกพร่องด้วยดัชนีที่ซ้ำกันนั้นยอดเยี่ยมมาก! ฉันไม่ได้สังเกตว่าจนกว่าฉันจะอ่านความคิดเห็นของคุณในคำตอบอื่น ๆ ขอบคุณ!
tupan

เกี่ยวกับการใช้งานที่คุณต้องการนำไปใช้ Pandas 0.24.1 คะแนนต่อไปนี้: 'พฤติกรรมของargmaxจะได้รับการแก้ไขเพื่อส่งคืนตำแหน่งสูงสุดในอนาคต สำหรับตอนนี้ใช้series.values.argmaxหรือnp.argmax(np.array(values))เพื่อให้ได้ตำแหน่งของแถวสูงสุด '
Sam

1
ในทำนองเดียวกัน.ixวิธีการของตัวอย่างที่สองได้รับการเปลี่ยนชื่อเป็น.iloc
Ma0

หากคอลัมน์ของคุณมีเฉพาะค่าน่านสิ่งนี้จะส่งผลให้ TypeError
Max Segal

77

คุณอาจลอง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

เช่น

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

ขอบคุณเวส เอกสารประกอบสำหรับ idxmax () ที่นี่: pandas.pydata.org/pandas-docs/dev/generated/…
จะ

df.ix[df['A'].idxmax()].valuesเพื่อคว้าอาเรย์ที่ฉันต้องการ ยังคงใช้งานได้
Yojimbo

2
โปรดทราบว่าคุณต้องระมัดระวังในการใช้เอาต์พุตidxmaxเป็นตัวป้อนลงในixหรือlocเป็นวิธีย่อยข้อมูลและ / หรือเพื่อให้ได้ตำแหน่งตำแหน่งของแถวสูงสุด เพราะคุณสามารถทำซ้ำในIndex- ดูการปรับปรุงคำตอบของฉันสำหรับตัวอย่าง
ely

25

คำตอบทั้งสองข้างต้นจะคืนค่าดัชนีเดียวหากมีหลายแถวที่รับค่าสูงสุด หากคุณต้องการแถวทั้งหมดดูเหมือนจะไม่มีฟังก์ชั่น แต่มันก็ไม่ยากที่จะทำ ด้านล่างเป็นตัวอย่างของซีรี่ส์ เดียวกันสามารถทำได้สำหรับ 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
ขอบคุณ! รุ่นสำหรับ DataFrame:df[df['A'] == df['A'].max()]
Dennis Golomazov

นี่คือคำตอบที่ถูกต้องจริง (รุ่น DataFrame)
gented

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

argmax()จะให้ดัชนีที่สอดคล้องกับค่าสูงสุดสำหรับ columnX ilocสามารถใช้เพื่อรับแถว DataFrame df สำหรับดัชนีนี้


4

โซลูชัน ".argmax ()" โดยตรงไม่ทำงานสำหรับฉัน

ตัวอย่างก่อนหน้านี้มีให้โดย@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

ส่งคืนข้อความต่อไปนี้:

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.

ดังนั้นทางออกของฉันคือ:

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

2
mx.iloc[0].idxmax()

รหัสหนึ่งบรรทัดนี้จะให้วิธีการหาค่าสูงสุดจากแถวใน dataframe นี่mxคือ dataframe และiloc[0]ระบุดัชนี 0


1

idmaxของ DataFrame ผลตอบแทนดัชนีป้ายชื่อของแถวที่มีค่าสูงสุดและลักษณะการทำงานของargmaxขึ้นอยู่กับรุ่นของpandas(ตอนนี้มันกลับคำเตือน) หากคุณต้องการใช้ดัชนีตำแหน่งคุณสามารถทำสิ่งต่อไปนี้:

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

หรือ

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

หมายเหตุว่าถ้าคุณใช้พฤติกรรมเช่นเดียวกับnp.argmax(df['A'])df['A'].argmax()

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.