首页 > 解决方案 > 组合数组以产生一个新的集体数组

问题描述

我需要以非常特定的方式组合三个(n,n)数组,以便产生n*n新数组,它们必须组合成一个大数组。

我基本上需要从每个数组中取出一个元素并创建一个新(3,3)数组,其中对角线是三个元素(其余为空),然后将这些新数组合并为一个。

正确解释有点困难。我试图在下面举一个例子,希望能对我正在尝试做的事情有所了解。

示例:给定三个(2,3)数组:

a = np.array([[2,5,9], [7,2,4]])
b = np.array([[3,6,2], [1,6,8]])
c = np.array([[8,7,4], [9,3,1]])

创建六个数组,其中 、 和 中的元素a作为b对角线c

T1 = ([[ 2, 0, 0],
       [ 0, 3, 0],
       [ 0, 0, 8]])

T2 = ([[ 5, 0, 0],
       [ 0, 6, 0],
       [ 0, 0, 7]])

T3 = ([[ 9, 0, 0],
       [ 0, 2, 0],
       [ 0, 0, 4]])

T4 = ([[ 7, 0, 0],
       [ 0, 1, 0],
       [ 0, 0, 9]])

T5 = ([[ 2, 0, 0],
       [ 0, 6, 0],
       [ 0, 0, 3])

T6 = ([[ 4, 0, 0],
       [ 0, 8, 0],
       [ 0, 0, 1]])

组合六个数组以产生

array([[ 2, 0, 0, 5, 0, 0, 9, 0, 0],
       [ 0, 3, 0, 0, 6, 0, 0, 2, 0],
       [ 0, 0, 8, 0, 0, 7, 0, 0, 4],
       [ 7, 0, 0, 2, 0, 0, 4, 0, 0],
       [ 0, 1, 0, 0, 6, 0, 0, 8, 0],
       [ 0, 0, 9, 0, 0, 3, 0, 0, 1]])

如在

array([[ T1, T2, T3],
       [ T4, T5, T6]])

*这六个数组本身不需要作为单独的数组,只需要最后一个数组。我刚刚选择了这条路线,因为它使最后一条路线的组成更加明显。

标签: pythonarraysnumpy

解决方案


可以通过以下方式完成einsum

ABC = np.array((a,b,c))
i,j,k = ABC.shape
out = np.zeros((i*j,i*k),ABC.dtype)
np.einsum("jiki->ijk",out.reshape(j,i,k,i))[...] = ABC
out
# array([[2, 0, 0, 5, 0, 0, 9, 0, 0],
#        [0, 3, 0, 0, 6, 0, 0, 2, 0],
#        [0, 0, 8, 0, 0, 7, 0, 0, 4],
#        [7, 0, 0, 2, 0, 0, 4, 0, 0],
#        [0, 1, 0, 0, 6, 0, 0, 8, 0],
#        [0, 0, 9, 0, 0, 3, 0, 0, 1]])

解释:

做什么的reshape

                            axis 2 (size k)
                       /-----------------------\
                            axis 3 (size i)
                       /-----\  /-----\  /-----\   
a  s /     a  s /    [[2, 0, 0, 5, 0, 0, 9, 0, 0],
x  i |     x  i |     [0, 3, 0, 0, 6, 0, 0, 2, 0],
i  z |     i  z \     [0, 0, 8, 0, 0, 7, 0, 0, 4],
s  e |     s  e /     [7, 0, 0, 2, 0, 0, 4, 0, 0],
     |          |     [0, 1, 0, 0, 6, 0, 0, 8, 0],
0  j \     1  i \     [0, 0, 9, 0, 0, 3, 0, 0, 1]]

它将 3x3 对角矩阵隔离为轴 1,3。

在这里做什么einsum

它将重塑的轴映射outABC; “jiki->ijk”表示轴 0(“j”)映射到轴 1,轴 1 和轴 3(“i”)映射到轴 0,轴 2(“k”)映射到轴 2。映射两个轴to one(与“i”一样)具有取对角线的特殊含义。

einsum创建一个可写视图,所以剩下要做的就是分配ABC给它。

注意:我们对形状和einsum规范使用相同的字母 i,j,k 在语法上没有任何意义,它只是让事情更具可读性。


推荐阅读