假设我有一个大小为(n* m ) x (n*m)的平方矩阵,它由n×n个子矩阵组成,每个子矩阵都是m×m的平方。
我想选择非对角子矩阵的对角线指数。这是我到目前为止拥有的代码,但如果可能的话,我想在不调用itertools.permutations的情况下这样做。
n_submatrix = 3
submatrix_size = 2
my_matrix = np.zeros([n_submatrix * submatrix_size,
n_submatrix * submatrix_size])
for submatrix_index in itertools.permutations(range(n_submatrix),2):
my_slice0 = slice(submatrix_index[0]*submatrix_size, (submatrix_index[0]+1)*submatrix_size)
my_slice1 = slice(submatrix_index[1]*submatrix_size, (submatrix_index[1]+1)*submatrix_size)
np.fill_diagonal(my_matrix[my_slice0,my_slice1],1)
my_matrix
#array([[ 0., 0., 1., 0., 1., 0.],
# [ 0., 0., 0., 1., 0., 1.],
# [ 1., 0., 0., 0., 1., 0.],
# [ 0., 1., 0., 0., 0., 1.],
# [ 1., 0., 1., 0., 0., 0.],
# [ 0., 1., 0., 1., 0., 0.]])发布于 2016-06-21 22:43:21
这种块状格式看起来像Kronecker product的作业,幸运的是,我们在np.kron中有一个内置的NumPy。此外,我们还需要使用np.eye来创建这样的块数组并将其提供给np.kron。所以,为了解决我们的案子,我们可以这样做-
np.kron(1-np.eye(n_submatrix),np.eye(submatrix_size))下面是一个样本,它的参数与问题中列出的参数相同-
In [46]: n_submatrix = 3
...: submatrix_size = 2
...:
In [47]: np.kron(1-np.eye(n_submatrix),np.eye(submatrix_size))
Out[47]:
array([[ 0., 0., 1., 0., 1., 0.],
[ 0., 0., 0., 1., 0., 1.],
[ 1., 0., 0., 0., 1., 0.],
[ 0., 1., 0., 0., 0., 1.],
[ 1., 0., 1., 0., 0., 0.],
[ 0., 1., 0., 1., 0., 0.]])发布于 2016-03-03 20:21:17
我肯定还有其他的方法,但与此同时,这个怎么样:
my_matrix = np.tile(np.eye(submatrix_size), (n_submatrix, n_submatrix))
np.fill_diagonal(my_matrix, 0)但是,矩阵的连接可能不是特别有效,所以我宁愿直接计算目标索引,填充它们,并可能再次清除对角线(在以前分配的矩阵上都是破坏性的):
cells = n_submatrix * submatrix_size
my_matrix = np.zeros((cells, cells))
for x in range(n_submatrix):
for y in range(submatrix_size):
r = range(y, n_submatrix * submatrix_size, submatrix_size)
my_matrix[x * submatrix_size + y, r] = 1
np.fill_diagonal(my_matrix, 0)这仍然很容易解释:我们首先根据子矩阵的数目(因为模式在那里重复),然后对每一行同时设置该行中的所有索引,由子矩阵中的当前步骤抵消。
同样,这似乎不如一次计算索引那么有效。最后,我得到了以下结果:
cells = n_submatrix * submatrix_size
my_matrix = np.zeros((cells, cells))
for y in range(submatrix_size):
r = range(y, n_submatrix * submatrix_size, submatrix_size)
my_matrix[np.ix_(r, r)] = 1
np.fill_diagonal(my_matrix, 0)公平地说,numpy.ix_和标引的文档并不是特别直观,但基本上我是在寻找一种方法来压缩“针对每一行,选择该行中的所有索引”的概念,然后一次性设置它们。现在子矩阵中的每一行只有一个循环,我没有想法了。
但是,可能有一个聪明的公式,可以一次生成所有索引(通过计算它们的模数)来生成所有对角。
顺便说一句。对于您的代码,我建议将表达式提取为变量(如上面的cells ),并可能提取更简洁的名称,但这只是我自己。
https://codereview.stackexchange.com/questions/121801
复制相似问题