根据给定公差截断二维数组[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相同。已解决。如果你同意的话,我将把第二个问题的答案添加到你的帖子中作为编辑。