在基本python中等效Numpy.argsort()?

Mer*_*moz 47 python numpy

在那里,做关于Python的内置函数python.array什么argsort()上呢numpy.array

unu*_*tbu 65

没有内置函数,但很容易从Python提供的极好工具中组装一个:

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]
Run Code Online (Sandbox Code Playgroud)

array.array以相同的方式在Python上运行:

import array
x = array.array('d', [5, 2, 1, 10])
print(argsort(x))
# [2, 1, 0, 3]
Run Code Online (Sandbox Code Playgroud)

  • 除了使用(理论上私有的) __getitem__ 之外,您还可以使用 `operator.itemgetter` / `operator.attrgetter` http://docs.python.org/library/operator.html (2认同)
  • 在我看来,`key=lambda i: seq[i]`可能更容易理解。 (2认同)

Bor*_*lik 60

我计时上面的建议,这是我的结果.

首先,功能:

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__)
Run Code Online (Sandbox Code Playgroud)

现在,IPython会话:

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
Run Code Online (Sandbox Code Playgroud)

FWIW

  • 有趣 - 可能平均值比3中的"最佳"更重要(?) (3认同)
  • 对于未来的读者来说,`%timeit`报告的平均值是3个平均值,每个100个循环. (3认同)
  • 平均值受到异常值的影响.您不希望运行的其他程序或硬件缓存未命中事件污染结果. (2认同)

Ton*_*nen 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]
Run Code Online (Sandbox Code Playgroud)

最好使用来自/sf/users/699331/的答案来对不带lambda表达式的线程python排序

[i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
Run Code Online (Sandbox Code Playgroud)