Pandas DataFrame - 查找列的值最大的行

时间:2012-04-18 03:59:56

标签: python pandas

如何找到特定列的值最大值的行?

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

12 个答案:

答案 0 :(得分:194)

您只需要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

此功能已更新为Pandas API中的名称idxmax,但从Pandas 0.16开始,argmax仍然存在并执行相同的功能(尽管运行速度比{{1}更慢})。

您也可以使用idxmax,例如numpy.argmax - 它提供与两个numpy.argmax(df['A'])函数中的任何一个相同的功能,并且至少与{{1}一样快在粗略的观察中。

以前(如评论中所述)似乎pandas将作为单独的函数存在,它在最大元素的行位置的索引中提供整数位置。例如,如果您将字符串值作为索引标签,例如行'a'到'e',您可能想知道最大值出现在第4行(而非行'd')。但是,在pandas 0.16中,上面列出的所有方法只提供了idxmax中所讨论行的标签,如果你想在{{{{}}中提供该标签的位置整数1}}你必须手动获取它(由于允许重复的行标签,这可能很棘手)。

一般情况下,我认为迁移到argmax - 就像所有三种方法(Index,仍然存在,Indexidxmax)的行为一样一件坏事,因为要求最大位置整数位置是非常常见的,甚至可能比在某些索引中需要该位置位置的标签更常见,特别是在重复行标签是常见的。

例如,请将此玩具argmax视为重复的行标签:

idxmax

所以这里天真地使用numpy.argmax是不够的,而DataFrame的旧形式会正确地提供最大行的位置位置(在这种情况下,位置9)。

这正是动态类型语言中那些令人讨厌的容易出错的行为之一,这使得这类事情变得如此不幸,值得打败死马。如果您正在编写系统代码并且您的系统突然被用于某些在加入之前未正确清理的数据集,则很容易最终出现重复的行标签,尤其是字符串标签,如金融资产的CUSIP或SEDOL标识符。您无法轻松使用类型系统来帮助您,并且您可能无法在索引上强制执行唯一性而不会遇到意外丢失的数据。

所以你希望你的单元测试涵盖所有内容(他们没有,或者更可能没有人写过任何测试) - 否则(很有可能)你只是等着看你是否碰巧在运行时遇到这个错误,在这种情况下,你可能不得不从输出结果的数据库中删除数小时的工作量,在IPython中试图手动重现问题,直到弄清楚它是因为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 只能 报告最大行的标签,然后感到失望的是没有标准函数自动获取位置最大的一行,你自己写一个错误的实现,编辑代码,并祈祷你不再遇到问题。

答案 1 :(得分:67)

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

e.g。

In [8]: df.loc[df['A'].idxmax()]
Out[8]: 
A    2.001289
B    0.482561
C    1.579985

答案 2 :(得分:19)

如果有多行采用最大值,则上述答案都只会返回一个索引。如果你想要所有的行,似乎没有一个功能。 但这并不难。以下是系列的示例; 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

答案 3 :(得分:8)

;with cte as (
    select *, ROW_NUMBER() over (partition by datepart(day,[time]) order by [time]) [rn]
    from #testTable
    where [type] in ('start','end')
)

select CAST(startTime as date) [Date],
       SUM([DifferenceInMinutes]) [DifferenceInMinutes]
from (
    select [c1].[id],
           [c1].[time] [startTime],
           ISNULL([c2].[time], cast(dateadd(day, 1, [c1].[time]) as date)) [endTime],
         DATEDIFF(minute, [c1].[time],ISNULL([c2].[time], cast(dateadd(day, 1, [c1].[time]) as date))) [DifferenceInMinutes]
    from cte [c1] left join cte [c2]
    on [c1].rn = [c2].[rn] - 1 and datepart(day,[c1].[time]) = datepart(day,[c2].[time])
    where [c1].[type] = 'start'
) a group by CAST(startTime as date)

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

答案 4 :(得分:4)

非常简单:我们具有df,如下所示,我们要在C中打印一个具有最大值的行:

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

答案 5 :(得分:1)

mx.iloc[0].idxmax()

这一行代码将为您提供如何从数据帧中的一行中查找最大值的方法,这里的“ mx”是数据帧,而iloc [0]表示第0个索引。

答案 6 :(得分:1)

直接的“ .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 :(得分:1)

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

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,这对于某些用例来说会很方便。

答案 8 :(得分:0)

DataFrame的idmax返回具有最大值的行的标签索引,argmax的行为取决于pandas的版本(现在它返回警告)。如果要使用位置索引,可以执行以下操作:

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

或     导入numpy为np     max_row = np.argmax(df [' A']。值)

请注意,如果您使用np.argmax(df['A'])的行为与df['A'].argmax()相同。

答案 9 :(得分:0)

以下是一些有用的例子,可以说明一切。

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

答案 10 :(得分:0)

如果您想要整个行而不是仅id,则可以使用df.nlargest并传入所需的“顶部”行数,还可以传入您要在哪个列/列中进行想要它。

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

将为您提供与A的前2个值相对应的行。

使用df.nsmallest作为最小值。

答案 11 :(得分:0)

考虑这个数据框

[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”列最大的行,以下将完成工作

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