简体   繁体   English

将Matlab代码转换为python 3.5+

[英]converting Matlab code to python 3.5+

I find some difficulties with fscanf and to do a wavelet transform order 2 on python 3.5. 我发现fscanf有一些困难,并且要在python 3.5上执行小波变换阶数2。 As well, I want to verify if the plot block is right. 同样,我想验证绘图块是否正确。 Here is my Matlab code: 这是我的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  

And below is my attempt with Python code 下面是我对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

The two problems are that your Python code is not doing the same thing as your MATLAB code in a lot of places, and your Python code is invalid in multiple places. 这两个问题是,您的Python代码在很多地方与MATLAB代码的功能不同,并且您的Python代码在很多地方都是无效的。

First, in the MATLAB code, this line continues to loop until you reach the end of the file: while(feof(D_P)==0)% . 首先,在MATLAB代码中,此行继续循环直到您到达文件末尾: while(feof(D_P)==0)% You apparently are trying to do the same thing with this line in python: if line == '': . 您显然正在尝试使用python中的这一行做同样的事情: if line == '': However, that runs the code only if the line is blank. 但是,仅在该行为空白时才运行代码。

You can use this approach in python, but you shouldn't. 您可以在python中使用此方法,但不应这样做。 You can just loop over the lines as though they were an array, using for line in D_P: . 您可以像使用数组一样for line in D_P:使用for line in D_P: This will automatically loop over the lines of D_P , putting each line in variable line . 这将自动在D_P的行上D_P ,将每行放在可变line Also, you should use with open ("distance_profil.txt","r") as D_P: to safely open and close the file, as is done in the ReadFile function. 另外,您应该使用with open ("distance_profil.txt","r") as D_P:来安全地打开和关闭文件,就像在ReadFile函数中所做的那样。 And you can use enumerate to keep track of the index with for i, line in enumerate(D_P): . 并且您可以使用enumerate来跟踪索引, for i, line in enumerate(D_P): You also try to read each line twice, which means you really end up reading every other line. 您还尝试读取每行两次,这意味着您实际上最终要阅读每隔一行。

The next problem is with this line cA= np.array(sign) . 下一个问题是与此行cA= np.array(sign) You do not define the sign variable anywhere. 您没有在任何地方定义sign变量。 It is defined in the ReadFile() function, which you never use and should delete. 它在ReadFile()函数中定义,您从不使用它,应该删除它。 So instead of using the sign variable, it is instead using the scipy.sign function, which you would have overriden if you had defined the sign variable. 因此,它不是使用sign变量,而是使用scipy.sign函数,如果定义了sign变量,则该函数将被覆盖。 That is why from ___ import * is a bad idea. 这就是为什么from ___ import *是个坏主意。 Use import scipy as sp or something like that. 使用import scipy as sp或类似的东西。 However, you don't need that since you only use one scipy function, which you import separately. 但是,您不需要这样做,因为您仅使用一个scipy函数,即可导入。

Unlike in MATLAB, functions are first-class objects in Python. 与MATLAB中不同,函数是Python中的一流对象。 You can use them like any other variable. 您可以像使用其他任何变量一样使用它们。 So you are creating an array containing one function rather than the numeric data you apparently intend. 因此,您正在创建一个包含一个函数而不是您显然打算使用的数字数据的数组。 This fails, however, for the dwt function, which needs numeric input. 但是,对于需要数字输入的dwt函数,此操作将失败。 What you need to do is convert the line of text into an array of numbers. 您需要做的是将文本行转换为数字数组。 The approach used in ReadLine is okay, except it is reading the wrong file and read the entire file instead of one line, did you copy that from somewhere? ReadLine使用的方法是可以的,除了它读取错误的文件并读取整个文件而不是一行,您是否从某个地方复制了该文件? However, it isn't a very good approach. 但是,这不是一个很好的方法。 It is better to use np.fromstring(line.strip(), sep=' ') . 最好使用np.fromstring(line.strip(), sep=' ') This will interpret a string as a sequence of numbers separated by spaces (replace with whatever you need) and convert it into a numpy array. 这会将字符串解释为由空格分隔的数字序列(替换为所需的数字)并将其转换为numpy数组。 This is faster and easier. 这样更快,更容易。

Next, with the dwt function, you assign to array[cA[i,], cD[i,]] . 接下来,使用dwt函数,将其分配给array[cA[i,], cD[i,]] This isn't doing what you want and won't work because there is no array variable. 这没有做您想要的事情,并且因为没有array变量而无法工作。 If array were a 2D numpy array, this would assign the results of dwt to the indexes at the coordinate corresponding to the value at index i of cA and cD . 如果array是2D numpy数组,则将dwt的结果分配cAcD索引i处的值相对应的坐标处的索引。 You just want to assign to cA and cD . 您只想分配给cAcD That means you can also remove the earlier definitions of cA and cD . 这意味着您也可以删除较早的cAcD定义。

Then, with the dwt call, you wrap the inputs in [] . 然后,通过dwt调用,将输入包装在[] In Python this passes a list as a single argument rather than the two arguments you want. 在Python中,它将列表作为单个参数而不是您想要的两个参数传递。 In MATLAB it wouldn't work either, since it would try to concatenate a numeric array with a character array (which will fail) and will also pass that as a single input to the function. 在MATLAB中,它也不起作用,因为它将尝试将数字数组与字符数组连接(这将失败),并将其作为单个输入传递给函数。 So do pywt.dwt(sign, 'db2') . pywt.dwt(sign, 'db2')

So that line would be: cA, cD = pywt.dwt(sign, 'db2') . 因此,该行应为: cA, cD = pywt.dwt(sign, 'db2')

Also, you use cdH several places, but never define it. 另外,您cdH多个地方使用了cdH ,但从未对其进行定义。 Is it supposed to be cD ? 应该是cD吗? Also with cdH([i,]) , MATLAB doesn't differentiate between function calls and array access, but python does. 同样使用cdH([i,]) ,MATLAB不会区分函数调用和数组访问,而python会。 You need to use square brackets [] and only square brackets for indexing. 您只需使用方括号[]并且仅需使用方括号进行索引。 cdH([i,]) will be interpreted as "call the function cdH with the list input [i,] , which won't work because cdH isn't a function (or wouldn't be if it were defined). The trailing comma is also redundant. So you just do cdh[i] . cdH([i,])将被解释为“使用列表输入[i,]调用函数cdH ,因为cdH不是一个函数(或者如果定义了,则不会)。它将不起作用。”尾部逗号也是多余的,因此您只需执行cdh[i]

Next, you define loc as an empty list, then define locs , then do loc = [loc, locs] . 接下来,将loc定义为一个空列表,然后定义locs ,然后执行loc = [loc, locs] In MATLAB, this appends locs to loc (which is redundant, but valid). 在MATLAB中,此附加locsloc (这是多余的,但有效的)。 In python, however, this creates a list that looks like [[], locs] , which is completely different. 但是,在python中,这会创建一个看起来像[[], locs] ,这是完全不同的。 You should just reduce those three lines to [pks,loc] = find_peaks_cwt(abs(cdH([i,]),'threshold',3) . 您只需将这三行减少为[pks,loc] = find_peaks_cwt(abs(cdH([i,]),'threshold',3)

Also, below, you write sign(2*locs) . 另外,在下面,您编写sign(2*locs) As I said, you need to use brackets for indexing, so this needs to be sign[2*locs] . 就像我说的那样,您需要使用方括号来建立索引,因此这需要是sign[2*locs]

Next, python doesn't have a mod function. 接下来,python没有mod函数。 Use % to do modulus in Python. 使用%在Python中做模数。 I am not sure what the mod with a single argument does in your version of MATLAB, in mine it raises and error. 我不确定带有单个参数的mod在您的MATLAB版本中会做什么,在我看来它会引发错误。 I assume from context, however, that you are trying to get the fractional part, which would be locs%1 . 但是,根据上下文,我假设您正在尝试获取小数部分,这将是locs%1

Finally, you do plt.plot(abs(cdH(i,)),locs,mod(locs),'ro') . 最后,执行plt.plot(abs(cdH(i,)),locs,mod(locs),'ro') Neither MATLAB nor Python would know how to plot with three arrays like this. MATLAB和Python都不知道如何绘制三个这样的数组。 You either need to split plt.plot(abs(cdH(i,))) into its own plot command like the MATLAB code does, or put np.arange(len(cdH(i,))) as the first argument to plot . 您需要像MATLAB代码一样将plt.plot(abs(cdH(i,)))拆分成它自己的plot命令,或者将np.arange(len(cdH(i,)))作为plot的第一个参数。 Same with the other plot. 与其他情节相同。

Overall, it seems like you aren't very familiar with either MATLAB or Python (or both). 总体而言,您似乎对MATLAB或Python(或两者)都不是很熟悉。 It would be worthwhile to brush up on the basics of both before trying to write code like those again. 在尝试再次编写类似代码之前,有必要梳理这两者的基础知识。

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

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