请考虑以下代码:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
Run Code Online (Sandbox Code Playgroud)
这给了我n
最小元素的索引.是否可以argsort
按降序使用它来获得n
最高元素的索引?
wim*_*wim 190
如果否定数组,则最低元素将成为最高元素,反之亦然.因此,n
最高要素的指数是:
(-avgDists).argsort()[:n]
Run Code Online (Sandbox Code Playgroud)
正如评论中所提到的,另一种推理这种情况的方法是观察大元素在argsort中的最后一个.所以,你可以从argsort的尾部读取以找到n
最高元素:
avgDists.argsort()[::-1][:n]
Run Code Online (Sandbox Code Playgroud)
两种方法的时间复杂度都是O(n log n),因为argsort
这里的调用是主导项.但是第二种方法有一个很好的优点:它用O(1)切片替换了数组的O(n)否定.如果你在循环中使用小数组,那么你可以通过避免这种否定获得一些性能提升,如果你正在使用大型数组,那么你可以节省内存使用,因为否定会创建整个数组的副本.
请注意,这些方法并不总是给出相同的结果:如果要求稳定的排序实现argsort
,例如通过传递关键字参数kind='mergesort'
,那么第一个策略将保持排序稳定性,但第二个策略将打破稳定性(即平等的位置)项目将被撤销).
daw*_*awg 68
就像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])
Run Code Online (Sandbox Code Playgroud)
这种方法的优点ids
是avgDists 的视图:
>>> ids.flags
C_CONTIGUOUS : False
F_CONTIGUOUS : False
OWNDATA : False
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
Run Code Online (Sandbox Code Playgroud)
('OWNDATA'为False表示这是一个视图,而不是副本)
另一种方法是这样的:
(-avgDists).argsort()[:n]
Run Code Online (Sandbox Code Playgroud)
问题是它的工作方式是在数组中创建每个元素的否定:
>>> (-avgDists)
array([-1, -8, -6, -9, -4])
Run Code Online (Sandbox Code Playgroud)
ANd创建了一个副本来执行此操作:
>>> (-avgDists_n).flags['OWNDATA']
True
Run Code Online (Sandbox Code Playgroud)
因此,如果您计算每个时间,即使使用这个非常小的数据集:
>>> 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
Run Code Online (Sandbox Code Playgroud)
视图方法明显更快
如果您只需要最低/最高 n 元素的索引,则np.argsort
可以使用而不是使用np.argpartition
。
这不需要对整个数组进行排序,而只需要对您需要的部分进行排序,但请注意,“分区内的顺序”是未定义的,因此虽然它提供了正确的索引,但它们可能无法正确排序:
>>> 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)
Run Code Online (Sandbox Code Playgroud)
正如@Kanmani 所暗示的那样,可以使用更易于解释的实现numpy.flip
,如下所示:
import numpy as np
avgDists = np.array([1, 8, 6, 9, 4])
ids = np.flip(np.argsort(avgDists))
print(ids)
Run Code Online (Sandbox Code Playgroud)
通过使用访问者模式而不是成员函数,更容易阅读操作顺序。
归档时间: |
|
查看次数: |
141705 次 |
最近记录: |