Найти строку, где значения столбца максимальны в панде DataFrame

Как найти строку, для которой значение определенного столбца максимальное?

df.max() даст мне максимальное значение для каждого столбца, я не знаю, как получить соответствующую строку.

Ответ 1

Вам просто нужна функция argmax() (теперь называемая 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

Эта функция была обновлена ​​до имени idxmax в API Pandas, хотя с Pandas 0.16, argmax все еще существует и выполняет ту же функцию (хотя она работает медленнее, чем idxmax)..

Вы также можете просто использовать numpy.argmax, например numpy.argmax(df['A']) - он обеспечивает то же самое, что и любая из двух функций pandas, и появляется как минимум с точностью idxmax в поверхностных наблюдениях.

Ранее (как отмечено в комментариях) оказалось, что argmax будет существовать как отдельная функция, которая обеспечивала бы целочисленную позицию в индексе расположения строки максимального элемента. Например, если у вас есть строковые значения в качестве ярлыков индексов, например, строки 'a' through 'e', ​​вы можете знать, что max встречается в строке 4 (а не в строке 'd'). Однако в Pandas 0.16 все перечисленные выше методы предоставляют только метку из Index для рассматриваемой строки, и если вы хотите, чтобы целое число позиции этой метки внутри Index, вы должны получить ее вручную (что может быть сложным теперь, когда допускаются дубликаты ярлыков строк).

В общем, я думаю, что переход к idxmax -подобному поведению для всех трех подходов (argmax, которые все еще существуют, idxmax и numpy.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.ix[dfrm['A'].idxmax()]
Out[21]: 
          A         B         C
i  0.688343  0.188468  0.352213
i  0.879000  0.105039  0.900260

Таким образом, наивное использование idxmax не является достаточным, тогда как старая форма argmax корректно обеспечит позиционное расположение максимальной строки (в данном случае - позиции 9).

Это точно один из тех неприятных видов склонности к ошибкам в динамически типизированных языках, что делает такие вещи такими неудачными и стоит победить мертвую лошадь. Если вы пишете системный код, и ваша система внезапно используется на некоторых наборах данных, которые не были очищены должным образом перед объединением, очень легко получить дублирующиеся ярлыки строк, особенно строковые метки, такие как идентификатор CUSIP или SEDOL для финансовых активов. Вы не можете легко использовать систему типов, чтобы помочь вам, и вы не сможете обеспечить уникальность индекса, не запуская неожиданно отсутствующих данных.

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

Ответ 2

Вы также можете попробовать 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

Ответ 3

Оба выше ответа вернут только один индекс, если есть несколько строк, которые принимают максимальное значение. Если вам нужны все строки, функция не работает. Но это не сложно. Ниже приведен пример серии; то же самое можно сделать для 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

Ответ 4

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

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

Ответ 5

mx.iloc[0].idxmax()

Эта строка кода покажет вам, как найти максимальное значение из строки в фрейме данных, здесь mx - это фрейм данных, а iloc [0] указывает на 0-й индекс.

Ответ 6

Прямое решение ".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()

Ответ 7

idmax объекта DataFrame возвращает индекс метки строки с максимальным значением, а поведение argmax зависит от версии pandas (сейчас он возвращает предупреждение). Если вы хотите использовать позиционный индекс, вы можете сделать следующее:

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

или импортировать numpy как np max_row = np.argmax(df ['A']. значения)

Обратите внимание, что если вы используете np.argmax(df['A']) ведет себя так же, как df['A'].argmax().

Ответ 8

Вот несколько полезных примеров, которые говорят сами за себя.

np.random.seed(0)                                                                                                      
df = pd.DataFrame(
    [[1, 2, 9], [7, 5, 6], [4, 8, 3]], columns=list('ABC'), index=list('xyz'))                           

df                                                                                                                     

   A  B  C
x  1  2  9
y  7  5  6
z  4  8  3

Индекс максимальной строки на столбец:

df.idxmax()                                                                                                            

A    y
B    z
C    x
dtype: object

# for a specific column, use
df['A'].idxmax()                                                                                                      
# 'y' 

Индекс максимального столбца в строке:

df.idxmax(axis=1)                                                                                                     

x    C
y    A
z    B
dtype: object

Целочисленная позиция максимальной строки в столбце:

df.idxmax().map(df.index.get_loc)                                                                                     

A    1
B    2
C    0
dtype: int64


# For a specific column, pass the label to 'Index.get_loc'
df.index.get_loc(df['A'].idxmax())                                                                                   
# 1

df['A'].to_numpy().argmax()                                                                                           
# 1

Заметка
В будущей версии Series.argmax будет дефакто для возврата максимальной позиции INTEGER. На данный момент он работает так же, как и Series.idxmax и возвращает FutureWarning. Пока что df['A'].to_numpy().argmax().

Целочисленная позиция максимального столбца в строке:

df.idxmax(axis=1).map(df.columns.get_loc)                                                                             

x    2
y    0
z    1
dtype: int64

# For a specific row,
df.columns.get_loc(df.loc['x'].idxmax())                                                                              
# 2