MATLAB转Python代码转换(NumPy,SciPy,MatplotLib?)

4
我正在尝试将以下代码从MATLAB转换为Python,用于EEG项目(部分原因是Python更便宜!)
希望有人可以指点我正确的方向:我已经开始修改了,但卡住了:特别是尝试找到等效函数。
尝试过scipy.org(NumPy_for_Matlab_Users等),但我不确定我的参数格式/数量是否正确
我最初使用了pyserial。
ser.read()

读取数据,然后...
ord()

将其转换为整数,但这段MATLAB代码采用了另一种方法('uchar')

我的主要问题在于

fopen
fread
find
repmat

我对Python中的绘图部分知之甚少(MatPlotLib?),希望你能帮忙翻译。

MATLAB通常以“1”开始,而Python使用0:我也尝试过进行更改,但有些不确定。

Python是否接受由冒号分隔的整个范围?

...repmat(0:2:10, .....

是否呢?

那么,这里是MATLAB:

% EEG data grabber and plotter

N = 256;    % Required number of sample frames

% Read in a block of data from the OpenEEG board
hCom = serial('COM1','BaudRate',57600,'timeout',5);
fopen(hCom);
numBlocks = (ceil(17*N/256) + 1);
rawdata = zeros(numBlocks*256,1);
for n = 1:numBlocks
    rawdata((0:255) + n*256) = fread(hCom, 256, 'uchar');  % Read data
end
fclose(hCom);

% Convert raw data into a Matlab matrix
% First find the first frame start
startIndex = find(rawdata == 165);
while(rawdata(startIndex(1) + 1) ~= 90)
   startIndex = startIndex(2:end);
end
% Now extract the samples
frameStarts = (0:(N-1))'*17 + startIndex(1);
indices = 4 + repmat(frameStarts, 1, 6) + repmat(0:2:10, length(frameStarts), 1);
eegData = (rawdata(indices)*256 + rawdata(indices + 1)) - 512;
% eegData is now a N by 6 matrix, each column is a channel of sampled data

% Plot time-series data
figure(1)
subplot(2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]');
ylabel('EEG data'); 
% Calculate FFT and plot spectra
subplot(2,1,2)
window = 0.5 - 0.5 * cos(2*pi*(0:255)/255); % Von-Hann Window
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)));
plot((0:127),f(1:128,:))
xlabel('Frequency [Hz]');
ylabel('EEG FFT');

这是我可怜的表兄版本

import scipy
import serial                       #Serial Module to read serial port
from numpy import ceil,zeros        #Ceil module & zeros for blank matrix

N = 256    #no of sample frames (256 = 1s)

#Reads a block of data from the serial port

ser = serial.Serial('COM18',57600,timeout=5)

scipy.fopen(ser)       #MATLAB CODE: fopen(ser)  is this correct????

numBlocks = (ceil(17*N/256) + 1)
rawdata = scipy.zeros(numBlocks*256,1)
for n = 1:numBlocks
    rawdata((0:255) + n*256) = numpyio.fread(ser,256,'i')  # read each byte as     unsigned integer
end
ser.close()


#convert raw data to MATLAB matrix
#find start of frame (1st Byte always 165, 2nd always 90)

startIndex = find(rawdata == 165);
while (rawdata(startIndex(0) + 1) ~=90) #confirms 165,90 sequence
    startIndex = startIndex(1:end) #uses rest of frame as data
end

#Extraction of sample values

#MATLAB CODE
frameStarts = (0: (N-1))'*17 + startIndex(1);      #'#how to transpose matrix('): zip()??
indices = 4 + (numpy.tile(frameStarts, 1,6)) + (numpy.tile(0:2:10,length(frameStarts), 1); 
eegData = (rawdata(indices)*256 + rawdata(indices +1)) - 512  #values are unsigned     integers 0-1023 and must subtract 512 for actual value
#eeg data now N*6 Matrix each column is a channel of data

#MATLAB CODE: plot time series data  (MatPlotLib?)

figure(1)
subplot (2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]')
ylabel('EEG Voltage')
#fft
subplot(2,1,2)
window = 0.5 - 0.5*cos(2*pi*(0:255)/255);
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)))    '#repmat=tile()? matrix     transposition (')?
plot((0:127),f(1:128,:))
xlabel('Freq [Hz]')
ylabel('EEG FFT')

非常感谢您提供的所有建议!

祝好!


3
你可以尝试使用Octave或者Scilab进行翻译,由于你的Python知识比较基础,所以放弃它并尝试其他工具也不会有太大损失。 - High Performance Mark
@H-gh-Performance Mark - Octave是否支持串行通信? - mtrw
3个回答

11

嗯...有很多东西。

Python没有end关键字,所以你需要更多地阅读Python的语法。

Python数组和切片用[]索引而不是()。例如,范围可以表示为range(0,10),但在Matlab中的切片只存在于扩展包(例如numpy)中,并且每个扩展包都有自己的接口。

是的,你想要使用matplotlib进行绘图,它几乎具有与Matlab相同的绘图界面能力,至少在这个层次上是如此。

看起来你猜测Python中会有与Matlab中某些随机包相同的方法名。这不是一个好计划。相反,查找Matlab方法的在线文档,确切地了解它的功能,然后阅读Python包文档以找到所需的方法。可能并不存在,但我敢打赌,在这么简单的程序中,你需要的大多数方法都会有。

将任何Matlab代码转换为其他语言最重要的是要理解Matlab数组的工作方式,这是非常不寻常的(但对其目标应用非常好)。Numpy具有大致相同的功能,但完全不同的表示法。

串行模块已经为你在端口上提供了一个打开的文件对象,所以你不需要使用fopen。

我认为你需要花很多时间阅读Python和Matlab的文档,因为目前很明显你都不理解。

不要让我打击你的信心,我只是对你现在的情况做出了诚实的评价。


3
我完全同意@Andrew McGregor的观点。将一个程序从一种语言移植到另一种语言是学习一种语言的好方法(我现在正在将一个类似的程序从MATLAB转换成Python),但这是学习两种语言的艰难之路! - mtrw
一个开源的Matlab自动转换成Python的转换器会是多么酷炫啊? - tylerthemiler
哈哈,是的,我发完帖子后去谷歌搜了一下。 - tylerthemiler

5

有一个小细节——两者之间的索引是不同的。如果您只是从MATLAB复制所有内容到Python中,就像您似乎已经做过的那样,您会非常困惑。MATLAB x(1:5:end) 对应于 Python x[0::5]。请返回NumPy for MATLAB Users,并向下滚动到名为“线性代数等效物”的部分(页面中部左右)。它提供了一个相互转换的字典。


2

这可能有用,也可能无效,但您可以尝试使用Matlab转Python转换器,例如mat2py。我从未尝试过它们,但这可能会节省一些时间。此外,这个页面关于Matlab转Numpy的转换,可能会帮助您了解两者之间的差异。


相关链接:https://dev59.com/Vmkw5IYBdhLWcg3wg6yg?rq=1 - 0 _

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接