Ответ 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
может только сообщать метку максимальной строки, а затем разочаровываться в том, что никакая стандартная функция автоматически не получает позиции максимальной строки для вас, самостоятельно записывая баггирование, редактируя код и молясь о том, чтобы вы не запускали в проблему снова.