Equivalent of Numpy.argsort() in basic python?
本问题已经有最佳答案,请猛点这里访问。
在
没有内置函数,但是很容易从Python提供的出色工具中组合出一个:
1 2 3 4 5 6 7 8 | def argsort(seq): # http://stackoverflow.com/questions/3071415/efficient-method-to-calculate-the-rank-vector-of-a-list-in-python return sorted(range(len(seq)), key=seq.__getitem__) x = [5,2,1,10] print(argsort(x)) # [2, 1, 0, 3] |
它以相同的方式在Python
1 2 3 4 | import array x = array.array('d', [5, 2, 1, 10]) print(argsort(x)) # [2, 1, 0, 3] |
我在上面建议了时间,这是我的结果。
首先,功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def f(seq): # http://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python/3383106#3383106 #non-lambda version by Tony Veijalainen return [i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))] def g(seq): # http://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python/3383106#3383106 #lambda version by Tony Veijalainen return [x for x,y in sorted(enumerate(seq), key = lambda x: x[1])] def h(seq): #http://stackoverflow.com/questions/3382352/equivalent-of-numpy-argsort-in-basic-python/3382369#3382369 #by unutbu return sorted(range(len(seq)), key=seq.__getitem__) |
现在,IPython会话:
1 2 3 4 5 6 7 8 9 10 | In [16]: seq = rand(10000).tolist() In [17]: %timeit f(seq) 100 loops, best of 3: 10.5 ms per loop In [18]: %timeit g(seq) 100 loops, best of 3: 8.83 ms per loop In [19]: %timeit h(seq) 100 loops, best of 3: 6.44 ms per loop |
FWIW
我的列举方法是:
1 2 3 4 5 6 7 | def argsort(seq): return [x for x,y in sorted(enumerate(seq), key = lambda x: x[1])] seq=[5,2,1,10] print(argsort(seq)) # Output: # [2, 1, 0, 3] |
最好使用来自https://stackoverflow.com/users/9990/marcelo-cantos的答案来对不带lambda表达式的线程python排序
1 | [i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))] |
找到了这个问题,但需要基于对象属性的argsort来获取对象列表。
扩展unutbu的答案,这将是:
1 | sorted(range(len(seq)), key = lambda x: seq[x].sort_property) |