在pandas数据框架中找到列值最大的行

怎样才能找到特定列的值为最大的行?

df.max()将给我每一列的最大值,我不知道如何获得相应的行。

416100 次浏览

使用pandas 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'].idxmax()
3
>>> df['B'].idxmax()
4
>>> df['C'].idxmax()
1
  • 或者你也可以使用numpy.argmax,比如numpy.argmax(df['A'])——它提供了同样的东西,粗略观察至少和idxmax一样快。

  • < p > idxmax()返回索引标签,而不是整数。

  • 如果你有字符串值作为你的索引标签,比如行'a'到'e',你可能想知道最大值出现在第4行(而不是'd')。

  • 如果你想要该标签在Index中的整数位置,你必须手动获取它(这可能很棘手,因为现在允许重复的行标签)。


历史记录:

  • idxmax()以前被称为argmax()在0.11之前
  • argmax在1.0.0之前已弃用,并在1.0.0中完全删除
  • 回到Pandas 0.16, argmax曾经存在并执行相同的功能(尽管似乎比idxmax运行得慢)。
  • argmax函数返回最大元素行位置索引内的整数位置
  • Pandas开始使用行标签而不是整数索引。位置整数索引过去非常常见,比标签更常见,特别是在重复行标签很常见的应用程序中。

例如,考虑这个玩具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可以只有报告max行的标签,然后失望地发现没有标准函数自动为你获得max行的职位,自己编写一个有bug的实现,编辑代码,并祈祷你不会再次遇到这个问题。

你也可以尝试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

如果有多行取最大值,以上两个答案都只返回一个索引。如果你想要所有的行,似乎没有一个函数。 但这并不难做到。下面是一个Series的例子;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

DataFrame的idmax返回最大值行的标签索引,而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()相同。

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

argmax()将提供与columnX的最大值对应的索引。iloc可用于获取该索引的DataFrame df的行。

mx.iloc[0].idxmax()

这一行代码将告诉你如何从dataframe中的一行中找到最大值,这里mx是dataframe, 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()

非常简单:我们有如下所示的df,我们想在C中打印一行max值:

A  B  C
x  1  4
y  2  10
z  5  9

:

df.loc[df['C'] == df['C'].max()]   # condition check

:

A B C
y 2 10

如果你想要整行而不仅仅是id,你可以使用df.nlargest并传入你想要的“top”行数,你也可以传入你想要它的列。

df.nlargest(2,['A'])

将给出与A的前两个值对应的行。

使用df.nsmallest来获取最小值。

使用查询()的更紧凑和可读的解决方案是这样的:

import pandas as pd


df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
print(df)


# find row with maximum A
df.query('A == A.max()')

它还返回一个DataFrame而不是Series,这对于某些用例来说很方便。

考虑这个数据框架

[In]: df = pd.DataFrame(np.random.randn(4,3),columns=['A','B','C'])
[Out]:
A         B         C
0 -0.253233  0.226313  1.223688
1  0.472606  1.017674  1.520032
2  1.454875  1.066637  0.381890
3 -0.054181  0.234305 -0.557915

假设一个人想知道列"C"是max,下面就可以了

[In]: df[df['C']==df['C'].max()])
[Out]:
A         B         C
1  0.472606  1.017674  1.520032

使用:

data.iloc[data['A'].idxmax()]

data['A'].idxmax() -根据行查找最大值位置 data.iloc() -返回

的行

如果最大值中有并列,则idxmax只返回第一个最大值的索引。例如,在下面的DataFrame中:

   A  B  C
0  1  0  1
1  0  0  1
2  0  0  0
3  0  1  1
4  1  0  0

idxmax回报

A    0
B    3
C    0
dtype: int64

现在,如果我们想要所有索引都对应于max值,那么我们可以使用max + eq来创建一个布尔型数据帧,然后在df.index上使用它来过滤索引:

out = df.eq(df.max()).apply(lambda x: df.index[x].tolist())

输出:

A       [0, 4]
B          [3]
C    [0, 1, 3]
dtype: object