将Matlab代码转换为Python

5

好的,我有一个来自EEG扫描的数据文件(一个二进制文件,data.eeg),在Matlab中,读取文件和绘制数据部分的代码如下:

sr=400;                                                     % Sample Rate
Nyq_freq=sr/2;                                              % Nyquist Frequency
fneeg=input('Filename  (with path and extension) :', 's');  
t=input('How many seconds in total of EEG ? : ');
ch=input('How many channels of EEG ? : ');
le=t*sr;                                                    % Length of the Recording
fid=fopen(fneeg, 'r', 'l');                                 % Open the file to read 
EEG=fread(fid,[ch,le],'int16');                             % Read Data -> EEG Matrix
fclose ('all');     
plot(EEG(:,3))

这是我尝试的“翻译”

from numpy import *
from matplotlib.pylab import *

sample_rate = 400
Nyquist = sample_rate/2.
fneeg = raw_input("Filename (full path & extension): ")
t = int(raw_input("How many secs in total of EEG?: "))
ch = int(raw_input("How many channels of EEG?: "))
le = t*sample_rate
fid = open(fneeg, 'r')
EEG = fromfile(fneeg, int16)

这里的事情让我感到困惑。根据文档,matlab的fread是通过fread(loaded_file, size, data_type)方法读取二进制文件的。在Python中,使用numpy的fromfile和reshape(根据此线程:MATLAB to Python fread)使用内置的reshape函数作为替代方案。我不确定这如何工作,甚至与matlab方法有何关系?如果我的问题令人困惑,我很抱歉,matlab对我来说还很新。
编辑:如果您想查看文件,请单击此处:https://www.dropbox.com/s/zzm6uvjfm9gpamk/data.eeg 编辑2:原始输入的答案是t=10,ch=32。实际上,我现在想起来了,我不确定为什么要询问用户输入..

你能发布一份输入文件的样本吗? - damienfrancois
1
听起来你已经回答了自己的问题。据我所知,你只需要 eeg = numpy.fromfile(filename, 'int16').reshape(ch, le)。此外,如果你愿意,你可以跳过显式打开文件的步骤。fromfile 函数也可以接受文件名作为参数,而不仅仅是文件对象。 - Joe Kington
我已经在编辑中添加了数据链接。@JoeKington,那也是我的想法,但为什么我们需要重新塑形呢?我不明白这个推理,你知道我的意思吗? - faskiat
1
@Norman,np.fromfile只返回一个1d数组(长度为ch*le),但您希望它成为一个chXle矩阵。 reshape 只是进行此更改,而不触及数据本身。 - askewchan
@Amyunimus 有什么问题? - faskiat
显示剩余5条评论
1个回答

2

如你自己和 @JoeKington 在评论中讨论的,这个应该可以工作(为了测试,我删除了输入内容)

import numpy as np

sample_rate = 400
Nyquist = sample_rate/2.0
fneeg = 'data.eeg'
t = 10 
ch = 32
le = t*sample_rate
EEG = np.fromfile(fneeg, 'int16').reshape(ch, le, order='F')

如果没有reshape,你会得到:

In [45]: EEG
Out[45]: array([ -39,  -25,  -22, ..., -168, -586,  -46], dtype=int16)

In [46]: EEG.shape
Out[46]: (128000,)

通过重新塑造:

In [47]: EEG.reshape(ch, le, order='F')
Out[47]: 
array([[ -39,  -37,  -12, ...,    5,   19,   21],
       [ -25,  -20,    7, ...,   20,   36,   36],
       [ -22,  -20,    0, ...,   18,   34,   36],
       ..., 
       [ 104,  164,   44, ...,   60,  -67, -168],
       [ 531,  582,   88, ...,   29, -420, -586],
       [ -60,  -63,  -92, ...,  -17,  -44,  -46]], dtype=int16)

In [48]: EEG.reshape(ch, le, order='F').shape
Out[48]: (32, 4000)

2
NormanB - 只是顺便提一下,Matlab可能使用列主序而不是行主序... http://en.wikipedia.org/wiki/Row-major_order 在这种情况下,结果可能以列主序写入磁盘,您需要执行 fromfile(...).reshape(le, ch).T(请注意,lech被交换)。 无论如何,这只是需要注意的一些事情。如果您的数据看起来混乱,请尝试一下。 - Joe Kington
噢,是的,你是对的(http://en.wikipedia.org/wiki/Row-major_order)。好发现! - faskiat
1
这实际上是从ipython(而不是notebook)复制并粘贴的。 这是ipython笔记本和标准python解释器之间的一个不错的折衷方案。 - askewchan
1
很好的发现,@Joe!更简单的解决方法是使用 order='F'。我已经编辑过来了。 - askewchan
@askewchan - order='F' 的确是个好点子!我总是忘记,最终会有很多难以阅读的 reshape(...).T - Joe Kington
显示剩余2条评论

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