Python 查找数据帧中最大值的所有索引

Python 查找数据帧中最大值的所有索引,python,pandas,Python,Pandas,我需要找到在数据帧中获得最大值(每行)的所有索引。例如,如果我有这样一个数据帧: cat1 cat2 cat3 0 0 2 2 1 3 0 1 2 1 1 0 然后,我正在寻找的方法将产生如下结果: [['cat2', 'cat3'], ['cat1'], ['cat1', 'cat2']] 这是一个列表列表,但其他一些数据结构也可以 我不能使用df.idxmax(axis=1),因为它只产生第一个最大值。

我需要找到在数据帧中获得最大值(每行)的所有索引。例如,如果我有这样一个数据帧:

   cat1  cat2  cat3
0     0     2     2
1     3     0     1
2     1     1     0
然后,我正在寻找的方法将产生如下结果:

[['cat2', 'cat3'],
 ['cat1'],
 ['cat1', 'cat2']]
这是一个列表列表,但其他一些数据结构也可以


我不能使用df.idxmax(axis=1),因为它只产生第一个最大值。

以下是不同数据结构中的信息:

In [8]: df = pd.DataFrame({'cat1':[0,3,1], 'cat2':[2,0,1], 'cat3':[2,1,0]})

In [9]: df
Out[9]: 
   cat1  cat2  cat3
0     0     2     2
1     3     0     1
2     1     1     0

[3 rows x 3 columns]

In [10]: rowmax = df.max(axis=1)
最大值由真值表示:

In [82]: df.values == rowmax[:,None]
Out[82]: 
array([[False,  True,  True],
       [ True, False, False],
       [ True,  True, False]], dtype=bool)
返回上面的数据帧为真的索引

In [84]: np.where(df.values == rowmax[:,None])
Out[84]: (array([0, 0, 1, 2, 2]), array([1, 2, 0, 0, 1]))
第一个数组表示轴=0的索引值,第二个数组表示轴=1的索引值。每个数组中有5个值,因为有五个位置为真


您可以使用
itertools.groupby
来构建您发布的列表列表,尽管鉴于上面的数据结构,您可能不需要这样做:

In [46]: import itertools as IT

In [47]: import operator

In [48]: idx = np.where(df.values == rowmax[:,None])

In [49]: groups = IT.groupby(zip(*idx), key=operator.itemgetter(0))

In [50]: [[df.columns[j] for i, j in grp] for k, grp in groups]
Out[50]: [['cat1', 'cat1'], ['cat2'], ['cat3', 'cat3']]
你可以

In [2560]: cols = df.columns.values

In [2561]: vals = df.values

In [2562]: [cols[v].tolist() for v in vals == vals.max(1)[:, None]]
Out[2562]: [['cat2', 'cat3'], 
            ['cat1'], 
            ['cat1', 'cat2']]
更新

以下是一个完整的示例:

import pandas as pd
import numpy as np

np.random.seed(400)

df = pd.DataFrame({
    'a': np.random.randint(0,3,size=10), 
    'b': np.random.randint(0,3,size=10), 
    'c': np.random.randint(0,5,size=10),
})

print(df)

out = [df.columns[i].tolist() for i in df.values == df.max(axis=1)[:,None]]

for i in out:
    print(i)
打印(df)
返回:

打印(输出)


df==DataFrame(np.tile(rowmax,len(df)).reforme(df.shape).T,index=df.index,columns=df.columns)
将获得布尔帧(有点像广播比较运算符);速度更快,但问题并不比应用更清楚。杰夫:好主意
df.values==rowmax[:,None]
速度快了10倍。非常感谢!除非我弄错了,否则你的最后一行应该是
[[df.columns[j]for I,j in grp]for k,grp in groups]
no?@unutbu实际上我认为它们是一个开放的问题,可以进行可广播的比较(例如div,mul等)-你也可以链接这个吗?(或者创建并发布,如果它们不是一个)谢谢!有兴趣做公关吗??(没那么复杂!)另一个问题(dupe)把我带到了这里。较短的版本:
[df.columns[i].tolist()表示df.values==df.max(axis=1)[:,None]
   a  b  c
0  0  1  4
1  2  2  4
2  1  1  1
3  0  1  3
4  2  2  1
5  1  1  1
6  0  2  4
7  2  0  2
8  2  1  3
9  2  2  4
['c']
['c']
['a', 'b', 'c']
['c']
['a', 'b']
['a', 'b', 'c']
['c']
['a', 'c']
['c']
['c']