Как найти строку, для которой значение определенного столбца максимальное?
df.max()
даст мне максимальное значение для каждого столбца, я не знаю, как получить соответствующую строку.
Как найти строку, для которой значение определенного столбца максимальное?
df.max()
даст мне максимальное значение для каждого столбца, я не знаю, как получить соответствующую строку.
Вам просто нужна функция 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
может только сообщать метку максимальной строки, а затем разочаровываться в том, что никакая стандартная функция автоматически не получает позиции максимальной строки для вас, самостоятельно записывая баггирование, редактируя код и молясь о том, чтобы вы не запускали в проблему снова.
Вы также можете попробовать 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
Оба выше ответа вернут только один индекс, если есть несколько строк, которые принимают максимальное значение. Если вам нужны все строки, функция не работает. Но это не сложно. Ниже приведен пример серии; то же самое можно сделать для 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
df.iloc[df['columnX'].argmax()]
argmax()
предоставит индекс, соответствующий максимальному значению для columnX. iloc
может использоваться для получения строки DataFrame df для этого индекса.
mx.iloc[0].idxmax()
Эта строка кода покажет вам, как найти максимальное значение из строки в фрейме данных, здесь mx - это фрейм данных, а iloc [0] указывает на 0-й индекс.
Прямое решение ".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()
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()
.
Вот несколько полезных примеров, которые говорят сами за себя.
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