Знайдіть рядок, де значення для стовпця є максимальними у пандах 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() повертає мітки індексів, а не цілі числа.

    • Приклад ': якщо у вас вказуються рядкові значення в якості міток індексу, як рядки' а 'через' е ', ви, можливо, захочете знати, що максимум виникає у рядку 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).

Це якраз одна з тих бридких видів поведінки, схильної до помилок, на динамічно набраних мовах, що робить подібні речі такими прикрими, і варто перебити мертвого коня. Якщо ви пишете системний код, і ваша система раптом звикає до деяких наборів даних, які не очищаються належним чином перед тим, як приєднатись, це дуже просто в кінцевому підсумку з дублікатами міток рядків, особливо мітками рядків, такими як ідентифікатор CUSIP або SEDOL для фінансових активів. Ви не можете легко використовувати систему типів, щоб допомогти вам, і ви, можливо, не зможете надати унікальність індексу, не натрапивши на несподівано відсутні дані.

Таким чином, ви залишаєтеся сподіватися, що ваші тести одиниці покрили все (вони цього не зробили, або, швидше за все, ніхто не написав жодних тестів) - інакше (швидше за все) вам просто залишається чекати, щоб побачити, чи трапиться ви в цю справу помилка під час виконання, в цьому випадку ви , ймовірно , доведеться йти падіння багато годин на суму роботи з бази даних ви виводячи результати, битися головою об стіну в IPython намагається вручну відтворити проблему, нарешті , з'ясувати , що це тому , що idxmaxможе тільки повідомте про мітку максимального рядка, а потім розчаруєтесь, що жодна стандартна функція автоматично не отримує для вас позиції максимальної рядки, самостійно записуючи помилкову реалізацію, редагуючи код і молячись, щоб ви знову не стикалися з проблемою.


13
Виходячи з коментаря, який є останнім до останнього, він виглядає argminі argmaxзалишиться частиною, DataFrameі різниця полягає лише в тому, чи хочете ви індекс чи етикетку. idxmaxдасть вам мітку місця, де відбувається максимум. argmaxдасть вам ціле число індексу.
ely

4
Інформація, надана для пояснення різниці між argmaxта idxmaxта як уникнути помилок із дублюваним індексом, була чудовою! Я цього не помічав, поки не прочитав ваш коментар в іншій відповіді. Дякую!
Тупан

Що стосується використання, яке ви хотіли б застосувати, Pandas 0.24.1 вказує на таке: "поведінка компанії argmaxбуде виправлена, щоб повернути позиційний максимум у майбутньому. Поки що, використовуйте series.values.argmaxабо, np.argmax(np.array(values))щоб отримати максимальний рядок. '
Сем

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схопити масив, який я хотів. все ще працює.
Йохімбо

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()]
Денніс Голомазов

Це фактично правильна відповідь (версія DataFrame).
покладено

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

argmax()забезпечив би індекс, що відповідає максимальному значенню для стовпцяX. ilocможе бути використаний для отримання рядка df DataFrame для цього індексу.


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()

Цей один рядок коду дасть вам змогу знайти максимальне значення з рядка в кадрі даних, ось mxцей кадр даних і iloc[0]вказує 0-й індекс.


1

The idmaxDataFrame повертає індекс мітки рядка з максимальним значенням і поведінка в 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().

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.