<p>我可以用<code>np.diag_indices</code>简化编码。我不认为效率是相对于一个快速的解决方案(如果可能的话)。让我们看看我是否可以简化我的开发历史</p>
<p>首先是指数</p>
<pre><code>In [2]: np.diag_indices(2)
Out[2]: (array([0, 1]), array([0, 1]))
</code></pre>
<p>更简单的开始;我们不需要2维开始,那些可以改变重塑。我们可能不需要结束维度,但我暂时不谈这个问题:</p>
^{pr2}$
<p>现在构建参考解决方案:</p>
<pre><code>In [4]: A2=np.zeros((4,2,2,3),int)
In [5]: A2[:,0,0,:]=A1
In [6]: A2[:,1,1,:]=A1
In [7]: A2
Out[7]:
array([[[[ 0, 1, 2],
[ 0, 0, 0]],
[[ 0, 0, 0],
[[[ 3, 4, 5],
[ 0, 0, 0]],
[[ 0, 0, 0],
[ 3, 4, 5]]],
...
[[[ 9, 10, 11],
[ 0, 0, 0]],
[ 0, 1, 2]]],
...
[[ 0, 0, 0],
[ 9, 10, 11]]]])
</code></pre>
<p>备选方案:</p>
<pre><code>In [8]: A3=np.zeros((4,2,2,3),int)
In [9]: i,j=np.diag_indices(2)
In [10]: A3[:,i,j,:]=A1
...
ValueError: shape mismatch: value array of shape (4,3) could not be broadcast to indexing result of shape (2,4,3)
</code></pre>
<p>第一次尝试时形状不匹配</p>
<pre><code>In [12]: A2[:,i,j,:]
Out[12]:
array([[[ 0, 1, 2],
[ 0, 1, 2]],
[[ 3, 4, 5],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 6, 7, 8]],
[[ 9, 10, 11],
[ 9, 10, 11]]])
In [13]: A2[:,i,j,:].shape
Out[13]: (4, 2, 3)
</code></pre>
<p>我们需要修改<code>A1</code>,以便它可以广播到目标插槽。在</p>
<pre><code>In [14]: A1.shape
Out[14]: (4, 3)
In [15]: A3[:,i,j,:] = A1[:,None,:]
In [16]: np.allclose(A2,A3)
Out[16]: True
</code></pre>
<p><code>A2[...,i,j,:] = A1[...,None,:]</code>应该处理您的示例。在</p>
<p>更简单的版本,从一维阵列开始,扩展到三维</p>
<pre><code>In [21]: a1=np.arange(3)
In [22]: a3=np.zeros((2,2,3),int)
In [23]: a3[...,i,j,:]=a1[...,None,:]
In [24]: a3[i,j,:]=a1 # equivalent since a1[None,:] is automatic
In [25]: a3
Out[25]:
array([[[0, 1, 2],
[0, 0, 0]],
[[0, 0, 0],
[0, 1, 2]]])
</code></pre>
<p><code>a3</code>没有<code>a1</code>值的重复模式;或者是这样?在</p>
<pre><code>In [36]: a3.flatten()
Out[36]: array([0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2])
</code></pre>
<p>正如您所发现的,用<code>as_strides</code>填充所有插槽很容易,但仅填充对角线很难:</p>
<pre><code>In [46]: ast(a1,shape=a3.shape, strides=(0,0,4))
Out[46]:
array([[[0, 1, 2],
[0, 1, 2]],
[[0, 1, 2],
[0, 1, 2]]])
</code></pre>