Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python和Matlab中平均频率的差异_Python_Matlab_Signal Processing_Fft_Mean - Fatal编程技术网

Python和Matlab中平均频率的差异

Python和Matlab中平均频率的差异,python,matlab,signal-processing,fft,mean,Python,Matlab,Signal Processing,Fft,Mean,我有这个,我想根据这个画出平均功率频率。我使用以下代码在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);

我有这个,我想根据这个画出平均功率频率。我使用以下代码在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
强积金计划的图则如下:

接下来,我将尝试在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快得多,在我的例子中,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()    
选择前22000个样本,结果如下:
我将继续回答这个问题

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的第一个值(仅第一个值)完全不同。其余的值是相同的。
我在这里也很困惑。帮助我。:)

“detrend”选项将导致第一个值(0 Hz或DC)的差异

默认设置为“常量”,从原始数据中删除直流分量

f, Pxx_den = signal.periodogram(x, fs, detrend=False)

Python代码中的外部
for
循环发生了什么变化?在MATLAB中,您在这里对数据加窗
FT=fft(EMG(i:i+N-1))
但是在Python中,它看起来像是对所有数据进行fft
FT=np.fft.fft(EMG,axis=0)
。。。另外,在这两种语言中,您都使用相同的整数对变量进行索引,但MATLAB使用基于1的索引,Python使用基于0的索引,因此您肯定会因此产生很多“一个接一个”的错误?顺便说一句,
MPF.append(NUM/DUM)
可以写成
MPF(end+1)=NUM/DUM,因此您不需要
z
计数器变量…@Dan首先,谢谢。我编辑了我的代码,但当我运行它时,我的内存也用完了。如果可能的话,你能运行它吗。这里是:对于范围内的i(0,len(EMG)-N):FT=np.fft.fft(EMG[i:(i+N)],轴=0)psd=FT*np.conj(FT)NFFT=len(FT)f=(np.arange(0,NFFT/2)*采样率)/N#N_1=np 0(NFFT/2)D_1=0 N_1=0 MPF=[]对于np.arange(1,NFFT/2)中的j:D#不要在评论中发布代码,编辑您的问题以添加代码。(2) 如果内存不足,我建议您首先在较小的数据集上测试它。复制您的
EMG.txt
文件,并将其减小到原始大小的10%,然后在此基础上测试这两个脚本。您的代码之所以如此缓慢,可能是因为您正在将数据帧转换为列表。这会复制数据,而使用列表执行此类操作的速度要慢得多。对于像这样非常简单的数据,
numpy.fromfile
就足够了,它将为您提供一个numpy数组。您还可以执行
df['EMG'].values
来获取numpy数组。MPF也应该是一个由零组成的numpy数组。D_1和F_1的计算可以矢量化。不要对循环索引使用
arange
,使用
range
,或者更好的方法(如果你不能矢量化的话)是在zip(f,psd)中对fj,psdj使用
(或者在python2中使用
izip
)。