在 pandas DataFrame 中查找列值最大的行
- 2025-01-13 08:52:00
- admin 原创
- 82
问题描述:
如何找到特定列的值最大的行?
df.max()
将给我每一列的最大值,我不知道如何获取相应的行。
解决方案 1:
使用 pandasidxmax
函数。它很简单:
>>> 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
粗略观察一样快。idxmax()
返回索引标签,而不是整数。示例”:如果您有字符串值作为索引标签,例如行“a”到“e”,您可能想知道最大值出现在第 4 行(而不是行“d”)。
如果您想要该标签内的整数位置,
Index
则必须手动获取它(这可能很棘手,因为允许重复的行标签)。
历史记录:
idxmax()
在 0.11 之前被称为argmax()
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
只能报告最大行的标签,然后失望地发现没有标准函数自动为您获取最大行的位置,自己编写一个有缺陷的实现,编辑代码,并祈祷您不会再次遇到该问题。
解决方案 2:
您也可以尝试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
解决方案 3:
如果有多行取最大值,上述两个答案都只会返回一个索引。如果你想要所有行,似乎没有函数。但这并不难做到。下面是 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
解决方案 4:
df.iloc[df['columnX'].argmax()]
argmax()
将提供与 columnX 的最大值相对应的索引。iloc
可用于获取此索引的 DataFrame df 的行。
解决方案 5:
使用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,这对于某些用例来说很方便。
解决方案 6:
非常简单:我们有如下所示的 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
解决方案 7:
如果您想要整行而不仅仅是id
,您可以使用df.nlargest
并传入您想要的“顶部”行数,还可以传入您想要的列/列。
df.nlargest(2,['A'])
将为您提供与 的前 2 个值相对应的行A
。
用于df.nsmallest
最小值。
解决方案 8:
直接“.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()
解决方案 9:
对我有用的是:
df[df['colX'] == df['colX'].max()]
df
然后您将获得其中最大值为的行colX
。
然后,如果您只想要索引,您可以.index
在查询末尾添加。
解决方案 10:
mx.iloc[0].idxmax()
这行代码将告诉您如何从数据框中的一行中找到最大值,这里mx
是数据框并iloc[0]
表示第 0 个索引。
解决方案 11:
考虑这个数据框
[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
解决方案 12:
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()
。
解决方案 13:
使用:
data.iloc[data['A'].idxmax()]
data['A'].idxmax()
- 根据行找到最大值位置data.iloc(
) - 返回行
解决方案 14:
如果最大值有平局,则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
+eq
创建一个布尔 DataFrame,然后使用它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
解决方案 15:
这里是通过索引号、列名和它的值来获取每行中最大值的解决方案:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
df
输出:
A B C
0 -2.196294 1.208198 0.107897
1 2.529756 -1.066739 0.457129
2 0.473766 -0.687910 -0.782231
3 1.057454 -0.337246 -0.657504
4 -0.996061 -0.286889 1.085691
得到最终结果:
for i in range(df.index.stop):
print(df.iloc[i].name,df.iloc[i].idxmax(),df.iloc[i].max())
# df.iloc[i].name => get name (or number) of index
# df.iloc[i].idxmax() => get the column name that has the max value
# df.iloc[i].max() => get the max value
输出:
0 B 1.20819817982694
1 A 2.529756243733713
2 A 0.4737656647602032 3 A 1.0574536031378394 4 C 1.0856908394815743
您可能想知道我应该打印索引还是列名?
假设您有按年份索引的数据,并且在列中有国家名称,并且您想查看哪个国家在每年的收益最大,则此方法将会有所帮助。
如果索引是日期时间,则可以将 for 循环更改为以下内容(如果出现错误):
for i in range(len(new_data)):
exp 输出日期和国家/地区:
1995 法国 15.5
1996 阿根廷 15.0
1997 阿根廷 15.9
1998 ESP 16.0