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

python pandas

155109 просмотра

6 ответа

8121 Репутация автора

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

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

Автор: lazy1 Источник Размещён: 18.04.2012 03:59

Ответы (6)


167 плюса

37260 Репутация автора

Решение

Вам просто нужна 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в Pandas API, хотя по состоянию на Pandas 0.16 argmaxвсе еще существует и выполняет ту же функцию (хотя, кажется, работает медленнее, чем idxmax).

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

Ранее (как отмечалось в комментариях) казалось, что это argmaxбудет существовать как отдельная функция, которая обеспечивает целочисленную позицию в индексе расположения строки максимального элемента. Например, если в качестве меток индекса у вас есть строковые значения, например строки от «а» до «е», вы можете узнать, что максимальное значение происходит в строке 4 (а не в строке «d»). Тем не менее, в пандах 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 для финансовых активов. Вы не можете легко использовать систему типов, чтобы помочь вам, и вы не сможете навязать уникальность индекса, не столкнувшись с неожиданно отсутствующими данными.

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

Автор: ely Размещён: 18.04.2012 04:31

64 плюса

54832 Репутация автора

Вы также можете попробовать 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
Автор: Wes McKinney Размещён: 18.04.2012 03:51

19 плюса

199 Репутация автора

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

0 плюса

1923 Репутация автора

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

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

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

Автор: Jonathan Размещён: 05.07.2017 07:00

4 плюса

443 Репутация автора

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

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

Автор: nAQ Размещён: 08.03.2018 09:00

0 плюса

13 Репутация автора

mx.iloc[0].idxmax()

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

Автор: Manjula Devi Размещён: 29.01.2019 04:38
Вопросы из категории :
32x32