简体   繁体   English

SVD - 矩阵变换Python

[英]SVD - Matrix transformation Python

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; 这样可以得到3个矩阵; where "s" contains the magnitudes that corresponds to u, v. 其中“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)

linalg.svd returns s in descending order. linalg.svd以降序返回s So to select the n highest numbers in s , you'd simply form 因此,要选择sn最高数字,您只需要形成

s[:n]

If you set the smaller values of s to 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 产生

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM