SVD - 矩阵变换 Python

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21514400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:01:41  来源:igfitidea点击:

SVD - Matrix transformation Python

pythonmatrixmatplotlibsvd

提问by Phorce

Trying to compute SVD in Python to find the most significant elements of a spectrum and created a matrix just containing the most significant parts.

尝试在 Python 中计算 SVD 以找到频谱中最重要的元素并创建一个仅包含最重要部分的矩阵。

In python I have:

在python中我有:

u,s,v = linalg.svd(Pxx, full_matrices=True)

This gives 3 matrices back; where "s" contains the magnitudes that corresponds to u, v.

这将返回 3 个矩阵;其中“s”包含对应于 u, v 的幅度。

In order to construct a new matrix, containing all of the significant parts of the signal, I need to capture the highest values in "s" and match them with the columns in "u" and "v" and the resulting matrix should give me the most significant part of the data.

为了构建一个包含信号所有重要部分的新矩阵,我需要捕获“s”中的最高值并将它们与“u”和“v”中的列匹配,结果矩阵应该给我数据中最重要的部分。

The problem is I don't know how I would do this in Python, for example, how do I find the highest numbers in "s" and select the columns in "u" and "v" in order to create a new matrix?

问题是我不知道如何在 Python 中执行此操作,例如,如何找到“s”中的最高数字并选择“u”和“v”中的列以创建新矩阵?

(I'm new to Python and numpy) so any help would be greatly appreciated

(我是 Python 和 numpy 的新手)所以任何帮助将不胜感激

Edit:

编辑:

import wave, struct, numpy as np, matplotlib.mlab as mlab, pylab as pl
from scipy import linalg, mat, dot;
def wavToArr(wavefile):
    w = wave.open(wavefile,"rb")
    p = w.getparams()
    s = w.readframes(p[3])
    w.close()
    sd = np.fromstring(s, np.int16)
    return sd,p

def wavToSpec(wavefile,log=False,norm=False):
    wavArr,wavParams = wavToArr(wavefile)
    print wavParams
    return  mlab.specgram(wavArr, NFFT=256,Fs=wavParams[2],detrend=mlab.detrend_mean,window=mlab.window_hanning,noverlap=128,sides='onesided',scale_by_freq=True)

wavArr,wavParams = wavToArr("wavBat1.wav")

Pxx, freqs, bins = wavToSpec("wavBat1.wav")
Pxx += 0.0001

U, s, Vh = linalg.svd(Pxx, full_matrices=True)
assert np.allclose(Pxx, np.dot(U, np.dot(np.diag(s), Vh)))

s[2:] = 0
new_a = np.dot(U, np.dot(np.diag(s), Vh))
print(new_a)

采纳答案by unutbu

linalg.svdreturns sin descending order. So to select the nhighest numbers in s, you'd simply form

linalg.svds按降序返回。因此,要选择 中的n最高数字s,您只需形成

s[:n]

If you set the smaller values of sto zero,

如果您将 的较小值设置s为零,

s[n:] = 0

then matrix multiplication would take care of "selecting" the appropriate columns of U and V.

然后矩阵乘法将负责“选择”U 和 V 的适当列。

For example,

例如,

import numpy as np
LA = np.linalg

a = np.array([[1, 3, 4], [5, 6, 9], [1, 2, 3], [7, 6, 8]])
print(a)
# [[1 3 4]
#  [5 6 9]
#  [1 2 3]
#  [7 6 8]]
U, s, Vh = LA.svd(a, full_matrices=False)
assert np.allclose(a, np.dot(U, np.dot(np.diag(s), Vh)))

s[2:] = 0
new_a = np.dot(U, np.dot(np.diag(s), Vh))
print(new_a)
# [[ 1.02206755  2.77276308  4.14651336]
#  [ 4.9803474   6.20236935  8.86952026]
#  [ 0.99786077  2.02202837  2.98579698]
#  [ 7.01104783  5.88623677  8.07335002]]


Given the data here,

鉴于这里数据

import numpy as np
import scipy.linalg as SL
import matplotlib.pyplot as plt

Pxx = np.genfromtxt('mBtasJLD.txt')
U, s, Vh = SL.svd(Pxx, full_matrices=False)
assert np.allclose(Pxx, np.dot(U, np.dot(np.diag(s), Vh)))

s[2:] = 0
new_a = np.dot(U, np.dot(np.diag(s), Vh))
print(new_a)
plt.plot(new_a)
plt.show()

produces

产生

enter image description here

在此处输入图片说明