给定一个矩阵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,:]作为占位符)。
编辑:澄清我的意思:
我有一个矩阵S1 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]]