我知道这个问题已经被问了一百次,但答案似乎总是"使用 numpy 的参数"。但要么我误解了大多数人在问什么,要么答案不正确。无论如何,我希望获得列表升序的索引。措辞令人困惑,因此例如,给定一个列表[4, 2, 1, 3]
我希望[3, 1, 0, 2]
得到一个列表。最小的项是1
,所以它得到索引0
,最大的项是4
所以它得到索引3
。在我看来,argsort
经常被建议,但它似乎并没有这样做。
from numpy import argsort
l = [4, 2, 1, 3]
print(argsort(l))
# [2, 1, 3, 0]
# Expected [3, 1, 0, 2]
显然,argsort正在做其他事情,那么它实际上在做什么,它与预期的行为有何相似之处,以至于它经常(错误地)被建议?而且,更重要的是,我怎样才能获得所需的输出?
argsort()
基本上是将您的列表转换为索引的排序列表。
l = [4, 2, 1, 3]
首先,它获取列表中每个元素的索引,因此新列表变为:
indexed=[0, 1, 2, 3]
然后,它根据原始列表中的项目对索引列表进行排序。如4:0 , 2:1 , 1:2 and 3:3
其中 : 表示"对应于"。
对我们得到的原始列表进行排序
l=[1, 2, 3, 4]
并放置旧列表的每个相应索引的值
new=[2,1,3,0]
所以基本上它根据原始列表对列表的索引进行排序。
"正确"或预期的答案的原因是因为你问错了问题!
你所追求的是排序后的元素排名,而 Numpy 的 argsort() 返回排序后的索引列表,如文档所示!这些不是一回事(正如您;)发现的那样)!
@hpaulj正确回答了我,但在评论中。而且你看不到他。他的回答对我帮助很大,它让我得到了我想要的。
import numpy as np
l = [4, 2, 1, 3]
print(np.argsort(np.argsort(l)))
返回:
[3, 1, 0, 2]
这是你所期望的。此方法返回数组的索引(如果已排序)。
⚠️ 但请注意,如果输入数组包含重复,则有一个有趣的效果:
import numpy as np
l = [4, 2, 1, 3, 4]
print(np.argsort(np.argsort(l)))
返回:
[3 1 0 2 4]
他可能不会伤害你,但他确实伤害了我。我是这样解决这个问题的:
import numpy as np
l = [4, 2, 1, 3, 4]
ret2 = np.vectorize(lambda val: np.searchsorted(np.unique(l), val))(l)
print('Returned', ret2)
print('Expected', [3, 1, 0, 2, 3])
返回:
Returned [3 1 0 2 3]
Expected [3, 1, 0, 2, 3]
诚然,由于vectorize
功能,我的解决方案会很慢。但是没有什么能阻止您使用 numba
.不过😉我还没有测试过.