<p>很有趣的问题!在解决这个问题的过程中,我学到了一些新的东西。你知道吗</p>
<p><strong>涉及的步骤:</strong></p>
<ul>
<li><p>首先,我们在这里介绍新的临时秘书处。所以,我们需要使用<code>cdist</code>来得到新旧pts之间的平方欧氏距离。在新的输出中,这些将被容纳在两个块中,一个位于旧距离的正下方,另一个位于旧距离的右侧。</p></li>
<li><p>我们还需要计算新pts中的<code>pdist</code>,并将其<code>square-formed</code>块放在新对角线区域的尾部。</p></li>
</ul>
<p>示意性地放置新的<code>D_n_N</code>如下所示:</p>
<pre><code>[ D_n cdist.T
cdist New pdist squarefomed]
</code></pre>
<p>总而言之,实施过程将遵循以下思路——</p>
<pre><code>cdists = cdist( xNew, xOld, 'sqeuclidean')
n1 = D_n.shape[0]
out = np.empty((n1+N,n1+N))
out[:n1,:n1] = D_n
out[n1:,:n1] = cdists
out[:n1,n1:] = cdists.T
out[n1:,n1:] = squareform(pdist(xNew, 'sqeuclidean'))
</code></pre>
<hr/>
<p><strong>运行时测试</p>
<p>接近-</p>
<pre><code># Original approach
def org_app(D_n, xNew):
sq_dists = pdist(np.row_stack([xOld, xNew]), 'sqeuclidean')
D_n_N = squareform(sq_dists)
return D_n_N
# Proposed approach
def proposed_app(D_n, xNew, N):
cdists = cdist( xNew, xOld, 'sqeuclidean')
n1 = D_n.shape[0]
out = np.empty((n1+N,n1+N))
out[:n1,:n1] = D_n
out[n1:,:n1] = cdists
out[:n1,n1:] = cdists.T
out[n1:,n1:] = squareform(pdist(xNew, 'sqeuclidean'))
return out
</code></pre>
<p>计时-</p>
<pre><code>In [102]: # Setup inputs
...: p = 3
...: n = 5000
...: xOld = np.random.rand(n * p).reshape([n, p])
...:
...: sq_dists = pdist(xOld, 'sqeuclidean')
...: D_n = squareform(sq_dists)
...:
...: N = 3000
...: xNew = np.random.rand(N * p).reshape([N, p])
...:
In [103]: np.allclose( proposed_app(D_n, xNew, N), org_app(D_n, xNew))
Out[103]: True
In [104]: %timeit org_app(D_n, xNew)
1 loops, best of 3: 541 ms per loop
In [105]: %timeit proposed_app(D_n, xNew, N)
1 loops, best of 3: 201 ms per loop
</code></pre>