我有以下矩阵:
,
和
其中每个元素是3x3矩阵(即A_01是3x3矩阵)。这意味着A和B张量是9x9矩阵。 不使用 for 命令,如何组合前面的方程式以获得:
目标是获得一个numpythonic解决方案,因为在实际情况下, A 和 B 矩阵的大小可以是(N,N)。
答案 0 :(得分:3)
您可以尝试类似
的内容import numpy as np
def checker_index(n, m=3):
"""create an index vector that addresses m blocks of n consecutive
elements with the blocks separated by gaps of n elements
"""
# the next line creates the array
# / 0 1 ... n-1 \
# | 2n 2n+1 ... 3n-1 |
# \ 4n 4n+1 ... 5n-1 /
i = np.arange(m*n).reshape((m, n)) + n*np.arange(m)[:, None]
# next line just puts the rows side by side
# now observe the these are precisely the places where you want to
# put your first row of of A's (with a leading id) in the first
# row of the target structure, and similarly with columns
# also, observe that one just needs to add n to get indices
# suitable for placing the first row/column of B's
return i.ravel()
def mingle(AA, BB, m=3):
"""combine AA and BB into the target structure
here AA and BB are the full 3x3 block matrices you define in
your question
"""
n = len(AA) // m
i1 = checker_index(n, m)
# ix_ creates an "open grid" from its arguments
# so indexing with y1, x1 below will select nm x nm elements
# contrast this with ...
y1, x1 = np.ix_(i1, i1)
i2 = i1 + n
y2, x2 = np.ix_(i2, i2)
IAA = AA.copy()
# ... the following line which only selects the diagonal,
# thus just mn elements
IAA[np.arange(m*n), np.arange(m*n)] = 1
out = np.empty((2*m*n, 2*m*n))
out[y1, x1] = IAA
out[y1, x2] = BB
out[y2, x1] = BB
out[y2, x2] = IAA
return out
Numpythonic够吗?
答案 1 :(得分:1)
这是一种方法 -
def matrix_combination(A,B):
N = A.shape[0]//3 # Size of each block
A4D = A.reshape(3,N,3,N)
B4D = B.reshape(3,N,3,N)
r,c = np.nonzero(~np.eye(3,dtype=bool))
out = np.zeros((6,N,6,N),dtype=A.dtype)
idx0 = 2*np.arange(3)
out[idx0[r],:,idx0[c]] = A4D[r,:,c]
out[idx0[r]+1,:,idx0[c]+1] = A4D[r,:,c]
out[idx0[r],:,idx0[c]+1] = B4D[r,:,c]
out[idx0[r]+1,:,idx0[c]] = B4D[r,:,c]
out = out.reshape(N*6,-1)
np.fill_diagonal(out,1)
return out
示例运行 -
In [41]: A
Out[41]:
array([[ 0, 0, 44, 98, 40, 69],
[ 0, 0, 22, 55, 51, 19],
[16, 58, 0, 0, 95, 95],
[90, 88, 0, 0, 47, 91],
[65, 96, 21, 50, 0, 0],
[15, 91, 23, 91, 0, 0]])
In [42]: B
Out[42]:
array([[ 0, 0, 20, 36, 85, 15],
[ 0, 0, 17, 78, 56, 55],
[86, 19, 0, 0, 60, 96],
[76, 30, 0, 0, 34, 36],
[73, 63, 28, 58, 0, 0],
[40, 19, 22, 96, 0, 0]])
In [43]: matrix_combination(A,B)
Out[43]:
array([[ 1, 0, 0, 0, 44, 98, 20, 36, 40, 69, 85, 15],
[ 0, 1, 0, 0, 22, 55, 17, 78, 51, 19, 56, 55],
[ 0, 0, 1, 0, 20, 36, 44, 98, 85, 15, 40, 69],
[ 0, 0, 0, 1, 17, 78, 22, 55, 56, 55, 51, 19],
[16, 58, 86, 19, 1, 0, 0, 0, 95, 95, 60, 96],
[90, 88, 76, 30, 0, 1, 0, 0, 47, 91, 34, 36],
[86, 19, 16, 58, 0, 0, 1, 0, 60, 96, 95, 95],
[76, 30, 90, 88, 0, 0, 0, 1, 34, 36, 47, 91],
[65, 96, 73, 63, 21, 50, 28, 58, 1, 0, 0, 0],
[15, 91, 40, 19, 23, 91, 22, 96, 0, 1, 0, 0],
[73, 63, 65, 96, 28, 58, 21, 50, 0, 0, 1, 0],
[40, 19, 15, 91, 22, 96, 23, 91, 0, 0, 0, 1]])
答案 2 :(得分:1)
只是为了它的乐趣(以及一对一的Divakar),这是一个非常紧凑的解决方案:
def mingle(AA, BB, m=3):
n = len(AA) // m
out = np.empty((m, 2, n, m, 2, n))
out[:, [0, 1], ..., [0, 1], :] = AA.reshape((1, m, n, m, n))
out[:, [0, 1], ..., [1, 0], :] = BB.reshape((1, m, n, m, n))
out.shape = m * 2 * n, m * 2 * n
out[np.arange(m * 2 * n), np.arange(m * 2 * n)] = 1
return out