SVD-матричное преобразование Python
попытка вычислить SVD в Python, чтобы найти наиболее значимые элементы спектра и создать матрицу, содержащую только наиболее значимые части.
в python у меня есть:
u,s,v = linalg.svd(Pxx, full_matrices=True)
Это возвращает 3 матрицы; где "s" содержит значения, соответствующие u, v.
чтобы построить новую матрицу, содержащую все значительные части сигнала, мне нужно захватить самые высокие значения в "s" и сопоставить их со столбцами в "u" и " v " и полученная матрица должны дать мне наиболее значительную часть данных.
проблема в том, что я не знаю, как это сделать в Python, например, как найти самые высокие числа в "s" и выбрать столбцы в "u" и "v", чтобы создать новую матрицу?
(Я новичок в 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)
1 ответов
linalg.svd
возвращает s
в порядке убывания. Итак, чтобы выбрать n
большой s
, вы просто сформируете
s[:n]
если вы установите меньшие значения s
к нулю,
s[n:] = 0
тогда матричное умножение позаботится о "выборе" соответствующих столбцов U и V.
например,
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]]
учитывая сведения здесь,
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()
производит