我有EMG signal,我想基于此article绘制平均电源频率。我使用以下代码在Matlab中实现它:
clear all;
close all;
EMG=load('EMG.txt');
N=1000; %my window
z=1;
fs=200 %sampling rate
for i=1:length(EMG)-N
DUM=0;
NUM=0;
FT=fft(EMG(i:i+N-1));
psd=FT.*conj(FT);
NFFT=length(fft2);
f = [1:NFFT/2]*fs/N;
for j=1:NFFT/2
NUM=NUM+f(j)*psd(j);
DUM=DUM+psd(j);
end
MPF(z)=NUM/DUM;
z=z+1;
end
MPF的情节是:
以下我试图在Python中做同样的事情。代码是:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('EMG.txt', names=['EMG'])
EMG=df['EMG'].tolist()
sampling_rate=200
N=1000 #my window
FT=np.fft.fft(EMG, axis=0)
psd=FT*np.conj(FT)
NFFT=len(FT)
f =(np.arange(0,NFFT/2)*sampling_rate)/N
NUM=0
DUM=0
MPF=[]
for j in np.arange(1,NFFT/2):
NUM=NUM+f[j]*psd[j]
DUM=DUM+psd[i]
MPF.append(NUM/DUM)
plt.plot(MPF)
plt.show()
为什么不同?
根据Dan在评论部分的建议,我修改我的Python代码如下,结果或多或少相同,除了Matlab代码比Python更快,在我的情况下,内存不足:
sampling_rate=200
N=1000
MPF=[]
for i in range(0,len(EMG)-N):
signal=EMG[i:(i+N)]
FT=np.fft.fft(signal, axis=0)
psd=FT*np.conj(FT)
NFFT=len(FT)
f =(np.arange(0,NFFT/2)*sampling_rate)/N
D_1=0
N_1=0
for j in np.arange(1,NFFT/2):
D_1=D_1+f[j]*psd[j]
N_1=N_1+psd[j]
MPF.append(D_1/N_1)
plt.plot(MPF)
plt.show()
答案 0 :(得分:1)
'detrend' 选项会导致第一个值(0 Hz 或 DC)的差异。
默认设置为'constant',即从原始数据中去除直流分量。
f, Pxx_den = signal.periodogram(x, fs, detrend=False)
答案 1 :(得分:0)
我将继续这个问题和答案。
1)在Matlab中,尝试使用内置函数meanfreq
,而medfreq
也将帮助您找到中值频率。
2)到目前为止,我还没有找到一个用Python解决均值/中值频率的软件包。
3)我还尝试用Python解决均值/中值频率。
然后按照Matlab meanfreq
中的计算步骤进行操作。 (在Matlab命令窗口中,键入edit meanfreq.m
,您会看到meanfreq
的源代码。该源代码会有所帮助。
4)以下是我基于Python的meanfreq
from scipy import signal
def meanfreq(x, fs):
f, Pxx_den = signal.periodogram(x, fs)
Pxx_den = np.reshape( Pxx_den, (1,-1) )
width = np.tile(f[1]-f[0], (1, Pxx_den.shape[1]))
f = np.reshape(f, (1, -1))
P = Pxx_den * width
pwr = np.sum(P)
mnfreq = np.dot(P, f.T)/pwr
return mnfreq
5)您可以调试我的和Matlab的这些源代码。
6)我的代码中还有一个小“ bug”,不是我的。调试它们时,您可能会发现Pxx的第一个(只有第一个值)完全不同。其余值相同。 我在这里也很困惑。帮帮我。:)