我有一个数字列表:
myList = [1, 2, 3, 100, 5]
现在,如果我对此列表进行排序以获取[1, 2, 3, 5, 100]
。
我想要的是来自的元素的索引
排序顺序中的原始列表,即[0, 1, 2, 4, 3]
--- ala MATLAB的sort函数返回两者
价值观和指数。
答案 0 :(得分:117)
接下来的事情:
>>> myList = [1, 2, 3, 100, 5]
>>> [i[0] for i in sorted(enumerate(myList), key=lambda x:x[1])]
[0, 1, 2, 4, 3]
enumerate(myList)
为您提供包含(索引,值)元组的列表:
[(0, 1), (1, 2), (2, 3), (3, 100), (4, 5)]
通过将列表传递给sorted
并指定一个函数来提取排序键(每个元组的第二个元素;这就是lambda
的用途),对列表进行排序。最后,原始索引为使用[i[0] for i in ...]
列表推导提取每个排序元素。
答案 1 :(得分:63)
myList = [1, 2, 3, 100, 5]
sorted(range(len(myList)),key=myList.__getitem__)
[0, 1, 2, 4, 3]
答案 2 :(得分:18)
enumerate
的答案很好,但我个人不喜欢用于按值排序的lambda。以下只是反转索引和值,并对其进行排序。所以它首先按值排序,然后按索引排序。
sorted((e,i) for i,e in enumerate(myList))
答案 3 :(得分:11)
使用enumerate
和itemgetter
更新了答案:
sorted(enumerate(a), key=lambda x: x[1])
# [(0, 1), (1, 2), (2, 3), (4, 5), (3, 100)]
将列表压缩在一起:元组中的第一个元素是索引,第二个是值(然后使用元组x[1]
的第二个值对其进行排序,x是元组)
或使用itemgetter
模块中的operator
:
from operator import itemgetter
sorted(enumerate(a), key=itemgetter(1))
答案 4 :(得分:4)
答案 5 :(得分:2)
为此目的使用 Numpy Packages 的最简单方法:
import numpy
s = numpy.array([2, 3, 1, 4, 5])
sort_index = numpy.argsort(s)
print(sort_index)
但是如果你想要你的代码应该使用 baisc python 代码:
s = [2, 3, 1, 4, 5]
li=[]
for i in range(len(s)):
li.append([s[i],i])
li.sort()
sort_index = []
for x in li:
sort_index.append(x[1])
print(sort_index)
答案 6 :(得分:1)
其他答案是错误的。
一次运行argsort
并不是解决方案。
例如,以下代码:
import numpy as np
x = [3,1,2]
np.argsort(x)
产生array([2, 0, 1], dtype=int64)
,这不是我们想要的。
答案应该是两次运行argsort
:
import numpy as np
x = [3,1,2]
np.argsort(np.argsort(x))
按预期提供array([2, 0, 1], dtype=int64)
。
答案 7 :(得分:1)
本质上,您需要执行argsort
,所需的实现取决于您要使用外部库(例如NumPy)还是要保持纯Python的依赖关系。
您需要问自己的问题是:您想要
不幸的是,问题中的示例并未明确说明所需的内容,因为两者都会给出相同的结果:
>>> arr = np.array([1, 2, 3, 100, 5])
>>> np.argsort(np.argsort(arr))
array([0, 1, 2, 4, 3], dtype=int64)
>>> np.argsort(arr)
array([0, 1, 2, 4, 3], dtype=int64)
argsort
实现如果您可以使用NumPy,则只需使用函数numpy.argsort
或方法numpy.ndarray.argsort
。
已经在其他一些答案中提到了没有NumPy的实现,因此我将根据the benchmark answer here
总结最快的解决方案。def argsort(l):
return sorted(range(len(l)), key=l.__getitem__)
要获取对数组/列表进行排序的索引,您只需在数组或列表上调用argsort
。我在这里使用的是NumPy版本,但是Python实现应该给出相同的结果
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(arr)
array([1, 2, 0, 3], dtype=int64)
结果包含获取排序数组所需的索引。
由于排序后的数组为[1, 2, 3, 4]
,因此argsorted数组包含原始元素中这些元素的索引。
1
,并且在原始索引中位于索引1
上,因此结果的第一个元素为1
。 2
在原始索引中的索引为2
,因此结果的第二个元素为2
。 3
在原始索引中的索引为0
,因此结果的第三个元素为0
。 4
,它位于原始索引的索引3
中,因此结果的最后一个元素是3
。在这种情况下,您需要应用argsort
两次:
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(np.argsort(arr))
array([2, 0, 1, 3], dtype=int64)
在这种情况下:
3
,这是第三大值,因此它在已排序的数组/列表中将具有索引2
,因此第一个元素是2
。 / li>
1
,这是最小值,因此在排序后的数组/列表中将有索引0
,因此第二个元素是0
。2
,这是第二个最小的值,因此它在排序的数组/列表中将具有索引1
,因此第三个元素是1
。 4
,这是最大值,因此在排序后的数组/列表中将有索引3
,因此最后一个元素是3
。答案 8 :(得分:0)
将numpy导入为np
用于索引
S=[11,2,44,55,66,0,10,3,33]
r=np.argsort(S)
[output]=array([5, 1, 7, 6, 0, 8, 2, 3, 4])
argsort按排序顺序返回S的索引
价值
np.sort(S)
[output]=array([ 0, 2, 3, 10, 11, 33, 44, 55, 66])
答案 9 :(得分:0)
我用perfplot(属于我的一个项目)对它们进行了快速性能检查,发现很难推荐除numpy之外的其他任何东西(请注意对数刻度):
用于复制情节的代码:
import perfplot
import numpy
def sorted_enumerate(seq):
return [i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
def sorted_enumerate_key(seq):
return [x for x, y in sorted(enumerate(seq), key=lambda x: x[1])]
def sorted_range(seq):
return sorted(range(len(seq)), key=seq.__getitem__)
def numpy_argsort(x):
return numpy.argsort(x)
perfplot.save(
"argsort.png",
setup=lambda n: numpy.random.rand(n),
kernels=[sorted_enumerate, sorted_enumerate_key, sorted_range, numpy_argsort],
n_range=[2 ** k for k in range(15)],
xlabel="len(x)",
logx=True,
logy=True,
)
答案 10 :(得分:0)
我们将创建另一个从0到n-1的索引数组 然后将其压缩到原始数组,然后根据原始值对其进行排序
ar = [1,2,3,4,5]
new_ar = list(zip(ar,[i for i in range(len(ar))]))
new_ar.sort()
`
答案 11 :(得分:0)
代码:
s = [2, 3, 1, 4, 5]
li = []
for i in range(len(s)):
li.append([s[i], i])
li.sort()
sort_index = []
for x in li:
sort_index.append(x[1])
print(sort_index)
试试这个,它对我有用!
答案 12 :(得分:0)
首先将您的列表转换为:
myList = [1, 2, 3, 100, 5]
为列表项添加索引
myList = [[0, 1], [1, 2], [2, 3], [3, 100], [4, 5]]
下一个:
sorted(myList, key=lambda k:k[1])
结果:
[[0, 1], [1, 2], [2, 3], [4, 5], [3, 100]]