用python创建子矩阵



给定一个矩阵S和一个二进制矩阵W,我想创建一个S的子矩阵对应于W的非零坐标

例如:

S = [[1,1],[1,2],[1,3],[1,4],[1,5]]
W = [[1,0,0],[1,1,0],[1,1,1],[0,1,1],[0,0,1]]
我想要得到矩阵
S_1 = [[1,1],[1,2],[1,3]]
S_2 = [[1,2],[1,3],[1,4]]
S_3 = [[1,3],[1,4],[1,5]]

我想不出一个好用的方法在python中实现这个。对于每个S_i,我能做的最好的是

S_1 = S[0,:]
for i in range(np.shape(W)[0]):
if W[i, 0] == 1:
S_1 = np.vstack((S_1, S[i, :]))

但是如果我想改变问题的维度,比如说,有100个S_i,为每个S_i写一个for循环似乎有点难看。(旁注:S_1应该初始化为一些空的2d数组,但我不能让它工作,所以初始化为S[0,:]作为占位符)。

编辑:澄清我的意思:

我有一个矩阵S
1 1
1 2
1 3 
1 4
1 5
我有一个二进制矩阵
1 0 0
1 1 0
1 1 1
0 1 1
0 0 1

给定二进制矩阵W的第一列

1
1
1
0
0

1位于第一、第二和第三个位置。所以我想创建S对应的子矩阵每个列的第一,第二和第三个位置,所以S_1(对应W的第一列)是

1 1
1 2
1 3
同样,如果我们看W 的第三列
0
0
1
1
1

1在最后三个坐标中所以我想要一个S的子矩阵每一列只有最后三个坐标,叫做S_3

1 3
1 4
1 5

所以给定任何一个二进制矩阵的第I列,我想要生成一个子矩阵S_i其中S_i的列包含S的列,但是只有对应于二进制矩阵第I列中1的位置的项。

使用W的转置而不是W本身可能更有用,这既有利于人类的可读性,也便于编写代码。这意味着影响每个S_i的条目被组合在W的一个内括号中,即在W的一行中,而不是像现在这样在一列中。

则S_i = np。数组[S[j,:] for j in np.shape(S)[0] if W_T[i,j] == 1],其中W_T是W的转置。如果你需要/想要坚持W的原样,你需要反转索引i和j。

对于外部循环,您可以尝试将其嵌套在另一个类似的推导式中,而不使用if语句-然而这可能会很尴尬,因为您实际上并没有构建一个输出矩阵(S_i可以很容易地具有不同的维度,除非您以某种方式保证在W的每列中具有相同数量的1)。这实际上提出了您想要的问题-这些数组S_i的列表?否则,如果它们像你写的那样是独立的变量,就没有好办法以一种通用的方式引用它们,因为它们没有索引。

Numpy可以直接这样做。

import numpy as np
S = np.array([[1,1],[1,2],[1,3],[1,4],[1,5]])
W = np.array([[1,0,0],[1,1,0],[1,1,1],[0,1,1],[0,0,1]])
for row in range(W.shape[1]):
print(S[W[:,row]==1])

输出:

[[1 1]
[1 2]
[1 3]]
[[1 2]
[1 3]
[1 4]]
[[1 3]
[1 4]
[1 5]]

最新更新