考虑下面的代码:

avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]

这给出了n个最小元素的下标。是否可以使用相同的argsort按降序得到n个最高元素的下标?


当前回答

另一种方法是在argsort的参数中只使用一个'-',例如:"df[np。Argsort (-df[:, 0])]",如果df是数据帧,你想要按第一列排序(由列号'0'表示)。适当地更改列名。当然,列必须是数字。

其他回答

可以使用翻转命令numpy.flipud()或numpy.fliplr()在使用argsort命令排序后按降序获取索引。那是我通常做的事。

就像Python一样,[::-1]颠倒argsort()返回的数组,[:n]给出最后n个元素:

>>> avgDists=np.array([1, 8, 6, 9, 4])
>>> n=3
>>> ids = avgDists.argsort()[::-1][:n]
>>> ids
array([3, 1, 2])

这个方法的优点是ids是avgdist的一个视图:

>>> ids.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False

('OWNDATA'为False表示这是一个视图,而不是一个副本)

另一种方法是:

(-avgDists).argsort()[:n]

问题是这种工作方式是为数组中的每个元素创建负数:

>>> (-avgDists)
array([-1, -8, -6, -9, -4])

ANd创建一个副本来这样做:

>>> (-avgDists_n).flags['OWNDATA']
True

所以如果你用这个很小的数据集计算每一个时间:

>>> import timeit
>>> timeit.timeit('(-avgDists).argsort()[:3]', setup="from __main__ import avgDists")
4.2879798610229045
>>> timeit.timeit('avgDists.argsort()[::-1][:3]', setup="from __main__ import avgDists")
2.8372560259886086

view方法基本上更快(并且使用1/2的内存…)

正如@Kanmani所暗示的,更容易解释的实现可能使用numpy。翻转,如下所示:

import numpy as np

avgDists = np.array([1, 8, 6, 9, 4])
ids = np.flip(np.argsort(avgDists))
print(ids)

通过使用访问者模式而不是成员函数,可以更容易地读取操作的顺序。

另一种方法是在argsort的参数中只使用一个'-',例如:"df[np。Argsort (-df[:, 0])]",如果df是数据帧,你想要按第一列排序(由列号'0'表示)。适当地更改列名。当然,列必须是数字。

用你的例子:

avgDists = np.array([1, 8, 6, 9, 4])

获取n个最大值的索引:

ids = np.argpartition(avgDists, -n)[-n:]

按降序排序:

ids = ids[np.argsort(avgDists[ids])[::-1]]

获得结果(n=4):

>>> avgDists[ids]
array([9, 8, 6, 4])