<p>首先,可以使用<a href="https://docs.python.org/3/library/functions.html#enumerate" rel="nofollow noreferrer">^{<cd1>}</a>将任何值的iterable转换为(index,value)对的iterable。在</p>
<p>但是如果你只是对它们进行排序,它将按索引排序,这并不是很有用。您需要按每个(index,value)对中的值进行排序。通常,在Python中,通过将<a href="https://docs.python.org/3/howto/sorting.html#key-functions" rel="nofollow noreferrer">key function</a>传递给<a href="https://docs.python.org/3/library/functions.html#sorted" rel="nofollow noreferrer">^{<cd2>}</a>来实现这一点。如该文档中的示例所示,<a href="https://docs.python.org/3/library/operator.html#operator.itemgetter" rel="nofollow noreferrer">^{<cd3>}</a>是一个完美的键函数。你可以很容易地修改你的自定义排序函数来使用键函数,就像<code>sorted</code>所做的那样,尽管在没有看到自定义排序函数的情况下演示如何使用键函数有点困难。<sup>1</sup></p>
<p>但在本例中,您可以使用<a href="https://docs.python.org/3/howto/sorting.html#the-old-way-using-decorate-sort-undecorate" rel="nofollow noreferrer">Decorate-Sort-Undecorate</a>习惯用法。您只需要按每个(index,value)对中的值进行排序,所以“装饰”所需做的就是将这些对颠倒。而且,如果您只希望索引而不是值来“取消装饰”,只需删除这些值。在</p>
<p>所以:</p>
<pre><code>indexed = enumerate(arr)
decorated = ((value, index) for index, value in indexed)
sortedpairs = my_sort_function(decorated)
indices = np.fromiter(index for (value, index) in sortedpairs)
</code></pre>
<p>……或者,把它们放在一起:</p>
^{pr2}$
<p>(当然,您可以使用一行代码,但我认为两行代码是最好的可读性平衡点。)</p>
<hr/>
<p>如果你不允许用你的函数来替换你的函数。事实上,文档甚至向您展示了如何做到这一点:</p>
<pre><code>def my_enumerate(sequence, start=0):
n = start
for elem in sequence:
yield n, elem
n += 1
</code></pre>
<p>或者,因为您不需要自定义开始值:</p>
<pre><code>def my_enumerate(sequence):
n = 0
for elem in sequence:
yield n, elem
n += 1
</code></pre>
<hr/>
<p>但是现在,你能做同样的事情,同时仍然利用numpy(至少是一些)的优势,将所有东西都作为数组而不是使用iterables吗?在</p>
<p>当然可以。我们可以做与<code>enumerate</code>相同的操作,甚至将值放在底部,这样就不需要整个翻转步骤:</p>
<pre><code>decorated = np.stack((arr, np.arange(len(arr))))
</code></pre>
<p>…然后分类。我假设您的自定义排序函数对列进行排序。也许你需要传入一个<code>axis</code>参数,或者排序<code>decorated.T</code>,或者其他什么;你应该知道你自己函数的API。在</p>
<pre><code>sorted_pairs = my_sorted_array_function(decorated)
</code></pre>
<p>现在,我们只取索引行:</p>
<pre><code>indices = sorted_pairs[1]
</code></pre>
<hr/>
<p><sub>1。对于初始实现,只需将every <code>x < y</code>更改为<code>key(x) < key(y)</code>,并使其正常工作。然后,您可以通过缓存键值来找出如何优化它,这样每个元素只调用<code>key</code>次,而不是每个元素调用<code>log(N)</code>次。</sub></p>