数字 pandas DataFrame 中 n 个最大值的(行,列)列表?

List of the (row, col) of the n largest values in a numeric pandas DataFrame?

给定一个 Pandas DataFrame 的数值,如何生成一个 .loc 单元格位置的列表,然后可以使用它来获得相应的 n整个 DataFame 中的最大值?

例如:

A B C D E
X 1.3 3.6 33 61.38 0.3
Y 3.14 2.71 64 23.2 21
Z 1024 42 66 137 22.2
T 63.123 111 1.23 14.16 50.49

3 的 n 将为值 1024137111.

生成 (row,col) 对

然后可以像往常一样将这些位置馈送到 .loc 以从 DataFrame 中提取这些值。即

df.loc['Z','A']
df.loc['Z','D']
df.loc['T','B']

注意:很容易将此题误认为是涉及 .idxmax 的题。这不适用,因为可能从第 n 个最大的行 and/or 列中选择了多个值。

诀窍是在 np.argsort

上使用 np.unravel_index

示例:

import numpy as np
import pandas as pd

N = 5
df = pd.DataFrame([[11, 3, 50, -3],
                   [5, 73, 11, 100],
                   [75, 9, -2, 44]])


s_ix = np.argsort(df.values, axis=None)[::-1][:N]
labels = np.unravel_index(s_ix, df.shape)
labels = list(zip(*labels))

print(labels) # --> [(1, 3), (2, 0), (1, 1), (0, 2), (2, 3)]
print(df.loc[labels[0]])  # --> 100

你可以试试:

>>> data = {0 : [1.3, 3.14, 1024, 63.123], 1: [3.6, 2.71, 42, 111], 2 : [33, 64, 66, 1.23], 3 : [61.38, 23.2, 137, 14.16], 4 : [0.3, 21, 22.2, 50.49] }
>>> df = pd.DataFrame(data)
>>> df
          0       1      2       3      4
0     1.300    3.60  33.00   61.38   0.30
1     3.140    2.71  64.00   23.20  21.00
2  1024.000   42.00  66.00  137.00  22.20
3    63.123  111.00   1.23   14.16  50.49
>>>
>>> a = list(zip(*df.stack().nlargest(3).index.labels))
>>> a
[(2, 0), (2, 3), (3, 1)]
>>> # then ...
>>> df.loc[a[0]]
1024.0
>>> 
>>> # all sorted in decreasing order ...
>>> list(zip(*df.stack().nlargest(20).index.labels))
[(2, 0), (2, 3), (3, 1), (2, 2), (1, 2), (3, 0), (0, 3), (3, 4), (2, 1), (0, 2), (1, 3), (2, 4), (1, 4), (3, 3), (0, 1), (1, 0), (1, 1), (0, 0), (3, 2), (0, 4)]

编辑: 在 pandas 版本 0.24.0 及更高版本中,MultiIndex.labels 已被 MultiIndex.codes 取代(参见 What’s new in 0.24.0 (January 25, 2019)).上面的代码会抛出AttributeError: 'MultiIndex' object has no attribute 'labels',需要更新如下:

>>> a = list(zip(*df.stack().nlargest(3).index.codes))
>>> a
[(2, 0), (2, 3), (3, 1)]

编辑 2: 这个问题已经成为一个“移动目标”,因为 OP 一直在改变它(这是我最后一个 update/edit)。在上次更新中,OP 的数据框如下所示:

>>> data = {'A' : [1.3, 3.14, 1024, 63.123], 'B' : [3.6, 2.71, 42, 111], 'C' : [33, 64, 66, 1.23], 'D' : [61.38, 23.2, 137, 14.16], 'E' : [0.3, 21, 22.2, 50.49] }
>>> df = pd.DataFrame(data, index=['X', 'Y', 'Z', 'T'])
>>> df
          A       B      C       D      E
X     1.300    3.60  33.00   61.38   0.30
Y     3.140    2.71  64.00   23.20  21.00
Z  1024.000   42.00  66.00  137.00  22.20
T    63.123  111.00   1.23   14.16  50.49

可以使用以下方法获得所需的输出:

>>> a = df.stack().nlargest(3).index 
>>> a
MultiIndex([('Z', 'A'),
            ('Z', 'D'),
            ('T', 'B')],
           )
>>>
>>> df.loc[a[0]]
1024.0