将Matlab代码转换为python 3.5+

时间:2016-11-28 12:42:14

标签: python matlab python-3.x matplotlib matlab-compiler

我发现fscanf有些困难,并且在python 3.5上做了小波变换2。同样,我想验证绘图块是否正确。 这是我的Matlab代码:

D_P=fopen('distance_profil.txt','r');
i=0;
  while(feof(D_P)==0)% test for end of file
    i=i+1;
    sign=fscanf(D_P,'%f , ');
    classe=fgetl(D_P);
    %Wavelet Transform
    [caH(i,:),cdH(i,:)] = dwt(sign,'db2');         
    %Segmentation    
    loc=[];
    [pks,locs] = findpeaks(abs(cdH(i,:)),'threshold',3);
    loc=[loc,locs];
    mod=abs(cdH(i,:));
    figure
    titre = ['distance profil : ' classe];

    subplot(2,1,1); plot(sign); title(titre); 
    hold on, plot(2*locs,sign(2*locs),'dr')
    subplot(2,1,2); plot(abs(cdH(i,:))); title('Module des Details coef. for db2');
    hold on, plot(locs,mod(locs),'dr')     
end  

以下是我对Python代码的尝试

import pywt
import numpy as np
from scipy.signal import find_peaks_cwt
from scipy import *
import matplotlib.pyplot as plt

D_P= open ("distance_profil.txt","r")
i=0

while True:
    line = D_P.readline().strip()
    if line == '':

        def ReadFile():
            sign = []
            with open('textfiledata.txt', 'rt') as myFile:
                for line in myFile:
                    sign.append(map(int, line.split(',')))
            return sign

        classe = D_P.readline().rstrip()
        cA= np.array(sign)
        cD= np.array(sign)

        i+=1

        array[cA[i,], cD[i,]] = pywt.dwt([sign, 'db2'])

        loc = []
        [pks,locs] = find_peaks_cwt(abs(cdH([i,]),'threshold',3)

        loc = [loc,locs]
        mod=abs(cdH[i,])  

        plt.figure()
        plt.subplot(2,2,1)
        plt.plot(sign,2*locs,sign(2*locs),'ro')
        plt.title('distance profil : ' , classe)

        plt.subplot(2,2,2)
        plt.plot(abs(cdH(i,)),locs,mod(locs),'ro')
        plt.title("Module des Details coef. for db2")

        plt.show()

    break

1 个答案:

答案 0 :(得分:4)

两个问题是你的Python代码在很多地方与你的MATLAB代码没有做同样的事情,你的Python代码在多个地方都是无效的。

首先,在MATLAB代码中,此行继续循环,直到到达文件末尾:while(feof(D_P)==0)%。你显然在尝试用python中的这一行做同样的事情:if line == '':。但是,仅当行为空时才会运行代码。

你可以在python中使用这种方法,但你不应该这样做。你可以使用for line in D_P:循环遍历这些行,就像它们是一个数组一样。这将自动循环D_P行,将每一行放在变量line中。此外,您应该使用with open ("distance_profil.txt","r") as D_P:来安全地打开和关闭文件,就像ReadFile函数中所做的那样。您可以使用enumerate跟踪for i, line in enumerate(D_P):的索引。您还尝试两次读取每一行,这意味着您最终会读取每一行。

下一个问题是此行cA= np.array(sign)。您没有在任何地方定义sign变量。它在ReadFile()函数中定义,您永远不会使用它并且应该删除它。因此,不是使用sign变量,而是使用scipy.sign函数,如果已定义sign变量,则应覆盖该函数。这就是from ___ import *是个坏主意的原因。使用import scipy as sp或类似的东西。但是,您不需要这样做,因为您只使用了一个scipy功能,您可以单独导入。

与MATLAB不同,函数是Python中的第一类对象。您可以像使用其他变量一样使用它们。因此,您要创建一个包含一个函数的数组,而不是您显然想要的数字数据。但是,对于需要数字输入的dwt函数,这会失败。您需要做的是将文本行转换为数字数组。 ReadLine中使用的方法是可以的,除了它读取错误的文件并读取整个文件而不是一行,你是从某个地方复制的吗?但是,这不是一个非常好的方法。最好使用np.fromstring(line.strip(), sep=' ')。这会将字符串解释为由空格分隔的数字序列(替换为您需要的任何数字)并将其转换为numpy数组。这更快更容易。

接下来,使用dwt功能,您可以指定array[cA[i,], cD[i,]]。由于没有array变量,因此您无法做您想做的事并且无法工作。如果array是2D numpy数组,则会将dwt的结果分配给与i的索引cA处的值对应的坐标处的索引{{1} }}。您只想分配到cDcA。这意味着您还可以删除cDcA的早期定义。

然后,通过cD调用,您将输入包装在dwt中。在Python中,它将列表作为单个参数传递,而不是您想要的两个参数。在MATLAB中它也不会工作,因为它会尝试将数值数组与字符数组(将失败)连接起来,并且还将它作为单个输入传递给函数。 []也是如此。

这条线将是:pywt.dwt(sign, 'db2')

此外,您使用cA, cD = pywt.dwt(sign, 'db2')几个地方,但从未定义它。应该是cdH吗?同样使用cD,MATLAB不区分函数调用和数组访问,但python确实如此。您需要使用方括号cdH([i,])和方括号来进行索引。 []将被解释为"使用列表输入cdH([i,])调用函数cdH,因为[i,]不是函数,因此无法正常工作(或者如果定义的话,就不会这样)。尾随逗号也是多余的。所以你只需cdH

接下来,您将cdh[i]定义为空列表,然后定义loc,然后执行locs。在MATLAB中,这会将loc = [loc, locs]追加到locs(这是多余的,但有效)。但是,在python中,这会创建一个看起来像loc的列表,这是完全不同的。您应该将这三行减少到[[], locs]

另外,在下面,你写[pks,loc] = find_peaks_cwt(abs(cdH([i,]),'threshold',3)。正如我所说,您需要使用括号进行索引,因此需要sign(2*locs)

接下来,python没有sign[2*locs]功能。使用mod在Python中执行模数。我不确定在你的MATLAB版本中带有单个参数的%是什么,在我的版本中它会引发错误。但是,我假设您正在尝试获取小数部分,即mod

最后,你做locs%1。 MATLAB和Python都不会知道如何使用这样的三个数组进行绘图。您需要将plt.plot(abs(cdH(i,)),locs,mod(locs),'ro')拆分为自己的plt.plot(abs(cdH(i,)))命令,就像MATLAB代码那样,或者将plot作为np.arange(len(cdH(i,)))的第一个参数。与其他情节相同。

总的来说,您似乎对MATLAB或Python(或两者)都不是很熟悉。在尝试再次编写代码之前,先了解两者的基础知识是值得的。