首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在子矩阵矩阵中,选择非对角子矩阵的对角线指标。

在子矩阵矩阵中,选择非对角子矩阵的对角线指标。
EN

Code Review用户
提问于 2016-03-03 17:08:11
回答 2查看 1.7K关注 0票数 3

假设我有一个大小为(n* m ) x (n*m)的平方矩阵,它由n×n个子矩阵组成,每个子矩阵都是m×m的平方。

我想选择非对角子矩阵的对角线指数。这是我到目前为止拥有的代码,但如果可能的话,我想在不调用itertools.permutations的情况下这样做。

代码语言:javascript
复制
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.]])
EN

回答 2

Code Review用户

回答已采纳

发布于 2016-06-21 22:43:21

这种块状格式看起来像Kronecker product的作业,幸运的是,我们在np.kron中有一个内置的NumPy。此外,我们还需要使用np.eye来创建这样的块数组并将其提供给np.kron。所以,为了解决我们的案子,我们可以这样做-

代码语言:javascript
复制
np.kron(1-np.eye(n_submatrix),np.eye(submatrix_size))

下面是一个样本,它的参数与问题中列出的参数相同-

代码语言:javascript
复制
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.]])
票数 1
EN

Code Review用户

发布于 2016-03-03 20:21:17

我肯定还有其他的方法,但与此同时,这个怎么样:

代码语言:javascript
复制
my_matrix = np.tile(np.eye(submatrix_size), (n_submatrix, n_submatrix))
np.fill_diagonal(my_matrix, 0)

但是,矩阵的连接可能不是特别有效,所以我宁愿直接计算目标索引,填充它们,并可能再次清除对角线(在以前分配的矩阵上都是破坏性的):

代码语言:javascript
复制
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)

这仍然很容易解释:我们首先根据子矩阵的数目(因为模式在那里重复),然后对每一行同时设置该行中的所有索引,由子矩阵中的当前步骤抵消。

同样,这似乎不如一次计算索引那么有效。最后,我得到了以下结果:

代码语言:javascript
复制
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 ),并可能提取更简洁的名称,但这只是我自己。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/121801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档