找到每行具有第二个最大值的列名(pandas)

时间:2018-02-13 10:45:42

标签: python pandas dataframe

基于这篇文章:Find the column name which has the maximum value for each row很清楚如何使用df.idxmax(axis=1)获取每行最大值的列名。

问题是,如何获得第2行,第3行等每行的最大值?

2 个答案:

答案 0 :(得分:2)

您需要numpy.argsort作为位置,然后按indexing重新排序列名:

np.random.seed(100)
df = pd.DataFrame(np.random.randint(10, size=(5,5)), columns=list('ABCDE'))
print (df)
   A  B  C  D  E
0  8  8  3  7  7
1  0  4  2  5  2
2  2  2  1  0  8
3  4  0  9  6  2
4  4  1  5  3  4

arr = np.argsort(-df.values, axis=1)
df1 = pd.DataFrame(df.columns[arr], index=df.index)
print (df1)
   0  1  2  3  4
0  A  B  D  E  C
1  D  B  C  E  A
2  E  A  B  C  D
3  C  D  A  E  B
4  C  A  E  D  B

验证

#first column
print (df.idxmax(axis=1))
0    A
1    D
2    E
3    C
4    C
dtype: object

#last column
print (df.idxmin(axis=1))
0    C
1    A
2    D
3    B
4    B
dtype: object

答案 1 :(得分:0)

虽然没有方法可以在一行中查找特定的排名,但您可以使用rank方法在pandas数据框中对元素进行排名。

例如,对于这样的数据框:

df = pd.DataFrame([[1, 2, 4],[3, 1, 7], [10, 4, 2]], columns=['A','B','C'])

>>> print(df)
      A  B  C
  0   1  2  4
  1   3  1  7
  2  10  4  2

您可以通过以下方式获取每一行的排名:

 >>> df.rank(axis=1,method='dense', ascending=False)
        A    B    C
     0  3.0  2.0  1.0
     1  2.0  3.0  1.0
     2  1.0  2.0  3.0

默认情况下,将rank应用于数据框并使用method='dense'将导致浮动排名。只需执行以下操作即可轻松解决此问题:

 >>> ranks = df.rank(axis=1,method='dense', ascending=False).astype(int)
 >>> ranks
        A  B  C
     0  3  2  1
     1  2  3  1
     2  1  2  3

pandas中查找索引有点棘手,但可以恢复以在条件上应用过滤器(即ranks==2):

>>> ranks.where(ranks==2)
      A    B   C
   0  NaN  2.0 NaN
   1  2.0  NaN NaN
   2  NaN  2.0 NaN    

应用where将仅返回与条件匹配的元素,并将其余元素设置为NaN。我们可以通过执行以下操作来检索列和行索引:

>>> ranks.where(ranks==2).notnull().values.nonzero()
    (array([0, 1, 2]), array([1, 0, 1]))

要检索行中的列索引或位置,这是您问题的答案

>>> ranks.where(ranks==2).notnull().values.nonzero()[0]
    array([1, 0, 1])

对于第三元素,您只需将where中的条件更改为ranks.where(ranks==3),依此类推其他等级。