[英]converting Matlab code to python 3.5+
我發現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
這兩個問題是,您的Python代碼在很多地方與MATLAB代碼的功能不同,並且您的Python代碼在很多地方都是無效的。
首先,在MATLAB代碼中,此行繼續循環直到您到達文件末尾: while(feof(D_P)==0)%
。 您顯然正在嘗試使用python中的這一行做同樣的事情: if line == '':
但是,僅在該行為空白時才運行代碼。
您可以在python中使用此方法,但不應這樣做。 您可以像使用數組一樣for line in D_P:
使用for line in D_P:
。 這將自動在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
的結果分配cA
和cD
索引i
處的值相對應的坐標處的索引。 您只想分配給cA
和cD
。 這意味着您也可以刪除較早的cA
和cD
定義。
然后,通過dwt
調用,將輸入包裝在[]
。 在Python中,它將列表作為單個參數而不是您想要的兩個參數傳遞。 在MATLAB中,它也不起作用,因為它將嘗試將數字數組與字符數組連接(這將失敗),並將其作為單個輸入傳遞給函數。 pywt.dwt(sign, 'db2')
。
因此,該行應為: cA, cD = pywt.dwt(sign, 'db2')
。
另外,您cdH
多個地方使用了cdH
,但從未對其進行定義。 應該是cD
嗎? 同樣使用cdH([i,])
,MATLAB不會區分函數調用和數組訪問,而python會。 您只需使用方括號[]
並且僅需使用方括號進行索引。 cdH([i,])
將被解釋為“使用列表輸入[i,]
調用函數cdH
,因為cdH
不是一個函數(或者如果定義了,則不會)。它將不起作用。”尾部逗號也是多余的,因此您只需執行cdh[i]
。
接下來,將loc
定義為一個空列表,然后定義locs
,然后執行loc = [loc, locs]
。 在MATLAB中,此附加locs
到loc
(這是多余的,但有效的)。 但是,在python中,這會創建一個看起來像[[], locs]
,這是完全不同的。 您只需將這三行減少為[pks,loc] = find_peaks_cwt(abs(cdH([i,]),'threshold',3)
。
另外,在下面,您編寫sign(2*locs)
。 就像我說的那樣,您需要使用方括號來建立索引,因此這需要是sign[2*locs]
。
接下來,python沒有mod
函數。 使用%
在Python中做模數。 我不確定帶有單個參數的mod
在您的MATLAB版本中會做什么,在我看來它會引發錯誤。 但是,根據上下文,我假設您正在嘗試獲取小數部分,這將是locs%1
。
最后,執行plt.plot(abs(cdH(i,)),locs,mod(locs),'ro')
。 MATLAB和Python都不知道如何繪制三個這樣的數組。 您需要像MATLAB代碼一樣將plt.plot(abs(cdH(i,)))
拆分成它自己的plot
命令,或者將np.arange(len(cdH(i,)))
作為plot
的第一個參數。 與其他情節相同。
總體而言,您似乎對MATLAB或Python(或兩者)都不是很熟悉。 在嘗試再次編寫類似代碼之前,有必要梳理這兩者的基礎知識。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.