<p>下面的方法比Francesco对示例数组的方法快几倍:</p>
<pre><code>In [7]: a[np.argmax(a['id'][None, :] == b[:, None], axis=1)]
Out[7]:
array([(0, 'H', 88.15726964130869), (3, 'H', 92.98550136344437),
(5, 'H', 128.05441039929008), (8, 'H', 111.13662092749307),
(12, 'H', 97.79700070323196), (13, 'H', 108.2841293816308),
(14, 'H', 64.41057325770373), (15, 'H', 91.44444608631304),
(16, 'H', 81.50506434964355), (18, 'H', 118.34835768605957)],
dtype=[('id', '<i4'), ('name', '|S1'), ('value', '<f8')])
In [8]: %timeit a[np.argmax(a['id'][None, :] == b[:, None], axis=1)]
100000 loops, best of 3: 11.6 us per loop
In [9]: %timeit indices = [i for i,id in enumerate(a['id']) if id in b]; a[indices]
10000 loops, best of 3: 66.9 us per loop
</code></pre>
<p>要了解它的工作原理,请看一下:</p>
<pre><code>In [10]: a['id'][None, :] == b[:, None]
Out[10]:
array([[False, False, False, True, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False],
... # several rows removed
[False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, True]], dtype=bool)
</code></pre>
<p>它是一个数组,其行数与<code>b</code>中的元素数相等,列数与<code>a</code>中的元素数相等。<code>np.argmax</code>然后找到每行中第一个<code>True</code>的位置,这是<code>a['id']</code>中<code>b</code>对应元素第一次出现的索引。</p>
<p>如上所示,对于小数组,这在性能上胜过python。但是如果<code>a</code>或<code>b</code>变得太大,那么<code>bool</code>s中间数组的大小可能会削弱性能。而且,<code>np.argmax</code>必须搜索整行,它永远不会提前脱离循环,如果<code>a</code>太长,这不是一件好事。我对使用类似方法的<a href="https://stackoverflow.com/questions/14559687/scipy-fast-1-d-interpolation-without-any-loop">this question</a>做了一些计时,对于中等大小的数组来说,这仍然是一条路。</p>
<p>弗朗西斯科的方法绝对不那么老套,更容易理解,而且对于一个样本大小的数组来说,性能差异是无关紧要的,我必须承认。但这并不能让你感觉像<a href="http://abstrusegoose.com/483" rel="nofollow noreferrer">this</a>。。。</p>