数字 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
将为值 1024
、137
和 111
.
生成 (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
给定一个 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
将为值 1024
、137
和 111
.
然后可以像往常一样将这些位置馈送到 .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