我有三个 (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]])
*这六个数组本身不需要作为单独的数组,只需要最终的数组。我刚刚选择了这条路线,因为它使最终路线的内容更加明显。
最佳答案
可以使用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
在这里做什么?
它将 reshape 后的 out
的轴映射到 ABC
的轴;
“jiki->ijk”表示轴 0 (“j”) 映射到轴 1,轴 1 和 3 (“i”) 映射到轴 0,轴 2 (“k”) 映射到轴 2。
将两个轴映射到一个(如“i”)具有获取对角线的特殊含义。
einsum
创建一个可写 View ,因此剩下要做的就是将 ABC
分配给它。
注意:我们对形状和 einsum 规范使用相同的字母 i、j、k 在语法上没有任何意义,它只是使内容更具可读性。
关于python - 组合数组以产生新的集体数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57258020/