根据给定公差截断二维数组[Python]
关于奇异值分解的一个老问题让我问这个问题: 如何将二维数组截断为由某个公差指定的列数根据给定公差截断二维数组[Python],python,truncate,svd,truncation,Python,Truncate,Svd,Truncation,关于奇异值分解的一个老问题让我问这个问题: 如何将二维数组截断为由某个公差指定的列数 具体地,请考虑下面的代码片段,它定义了1E-4的可接受的公差,并将奇异值分解应用到矩阵“A”。 #Python tol=1e-4 U,Sa,V=np.linalg.svd(A) S=np.diag(Sa) 由此产生的奇异值对角矩阵‘S’保持非负奇异值的数量级递减 我想要得到的是一个截断的“S”矩阵,在某种程度上,矩阵中包含小于1e-4的奇异值的列将被删除。然后,将此截断应用于矩阵“U” 有没有一个简单的方法可
具体地,请考虑下面的代码片段,它定义了1E-4的可接受的公差,并将奇异值分解应用到矩阵“A”。
#Python
tol=1e-4
U,Sa,V=np.linalg.svd(A)
S=np.diag(Sa)
由此产生的奇异值对角矩阵‘S’保持非负奇异值的数量级递减
我想要得到的是一个截断的“S”矩阵,在某种程度上,矩阵中包含小于1e-4的奇异值的列将被删除。然后,将此截断应用于矩阵“U”
有没有一个简单的方法可以做到这一点?我一直在四处寻找,并为Matlab找到了一些问题的解决方案,但没有为Python找到任何类似的解决方案。
对于Matlab,代码如下所示:
%Matlab
tol=1e-4
mask=any(Sigma>=tol,2);
sigRB=Sigma(:,mask);
mask2=any(U>=tol,2);
B=U(:,mask);
提前谢谢。我希望我的帖子不是太乱而无法理解。我不确定我是否正确理解了你。如果我的解决方案不是你想要的,请考虑给你的问题增加一个例子。< /P> 下面的代码将删除数组
s
中仅包含小于tol
的值的所有列
s=np.array([
[1, 0, 0, 0, 0, 0],
[0, .9, 0, 0, 0, 0],
[0, 0, .5, 0, 0, 0],
[0, 0, 0, .4, 0, 0],
[0, 0, 0, 0, .3, 0],
[0, 0, 0, 0, 0, .2]
])
印刷品
tol=.4
ind=np.arg其中(s.max(轴=1)
输出:
[[1. 0. 0. 0. 0. 0. ]
[0. 0.9 0. 0. 0. 0. ]
[0. 0. 0.5 0. 0. 0. ]
[0. 0. 0. 0.4 0. 0. ]
[0. 0. 0. 0. 0.3 0. ]
[0. 0. 0. 0. 0. 0.2]]
[[1. 0. 0. 0. ]
[0. 0.9 0. 0. ]
[0. 0. 0.5 0. ]
[0. 0. 0. 0.4]
[0. 0. 0. 0. ]
[0. 0. 0. 0. ]]
我将max
应用于轴1,然后使用np.argwhere
获取最大值小于tol
的列的索引
编辑:为了截断矩阵“U”的列,使其与缩减后的矩阵“S”的大小一致,以下代码起作用:
k = len(S[0])
Ured = U[:,0:k]
Uredsize = np.shape(Ured) # To check it has worked
print(Uredsize)
对这就是我要问的。我尝试了你的解决方案,它成功了。非常感谢你。然后如何将相同行的截断应用于矩阵“U”?我不认为argwhere可以处理这个问题,因为“U”的值不符合顺序。是否可以这样做:定义一个列数为“S”的变量,然后以某种方式将矩阵“U”截断为定义的列数?当我正确理解您的matlab代码时,您使用的是U的方式。即
ind2=np.argwhere(U.max(axis=1)
。我不确定这是否正确。我猜您必须删除U的行而不是列。在这种情况下,更改为axis=0
应该可以工作。不,对不起;我想我没有正确地表达自己。这样做的目的是删除“U”中与我在“S”中删除的列数相同的列数。公差仅在“S”中有用,因为值是按降序排列的U’的尺寸必须与S相同。已解决。如果你同意的话,我将把第二个问题的答案添加到你的帖子中作为编辑。