考虑下面的代码:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
这给出了n个最小元素的下标。是否可以使用相同的argsort按降序得到n个最高元素的下标?
考虑下面的代码:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
这给出了n个最小元素的下标。是否可以使用相同的argsort按降序得到n个最高元素的下标?
当前回答
可以使用翻转命令numpy.flipud()或numpy.fliplr()在使用argsort命令排序后按降序获取索引。那是我通常做的事。
其他回答
您可以创建数组的副本,然后将每个元素与-1相乘。 结果,前面最大的元素会变成最小的元素。 副本中最小的n个元素的折号就是原始文件中最大的n个元素。
就像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的内存…)
一种优雅的方式可以如下-
ids = np.flip(np.argsort(avgDists))
这将给出按降序排序的元素索引。 现在你可以使用常规切片…
top_n = ids[:n]
而不是用np。Argsort你可以用np。Argpartition -如果你只需要最低/最高n个元素的索引。
这并不需要对整个数组进行排序,只需要对你需要的部分进行排序,但请注意“分区内的顺序”是未定义的,所以虽然它给出了正确的索引,但它们的顺序可能并不正确:
>>> avgDists = [1, 8, 6, 9, 4]
>>> np.array(avgDists).argpartition(2)[:2] # indices of lowest 2 items
array([0, 4], dtype=int64)
>>> np.array(avgDists).argpartition(-2)[-2:] # indices of highest 2 items
array([1, 3], dtype=int64)
可以使用翻转命令numpy.flipud()或numpy.fliplr()在使用argsort命令排序后按降序获取索引。那是我通常做的事。