Parsing a binary file written in MATLAB from Python and vice versa
我在python中遇到
我可以用Python将二进制数据写入文件,然后再读回数据。我还可以将相同的数据从MATLAB写入二进制文件,然后在MATLAB中毫无问题地读回。
当我从MATLAB写入数据并尝试以Python读取数据时,或者在Python中写入数据并尝试以MATLAB读取数据时,就会出现我的问题。
为了简单起见,假设我正在将两个整数写入二进制文件(big-endian)。每个整数为4个字节。第一个整数是不超过4个字节的有效整数,第二个整数必须等于1、2或3。
首先,这是我如何在MATLAB中写入数据:
1 2 3 4 5 6 7 8 | fid=fopen('hello_matlab.test','wb'); first_data=4+4; second_data=1; fwrite(fid,first_data,'int'); fwrite(fid,second_data,'int'); fclose(fid); |
这是我在MATLAB中读到的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 | fid=fopen('hello_matlab.test','rb'); first_data=fread(fid,1,'int'); second_data=fread(fid,1,'int'); fprintf('first data: %d\ ', first_data); fprintf('second data: %d\ ', second_data); fclose(fid); >> first data: 8 >> second data: 1 |
现在,这是我如何用Python编写数据的方法:
1 2 3 4 5 6 7 8 | fid=open('hello_python.test','wb') first_data=4+4 second_data=1 fid.write(struct.pack('>i',first_data)) fid.write(struct.pack('>i',second_data)) fid.close() |
这就是我如何用python读取数据的方法。还要注意,注释掉的部分有效(当读取用Python编写的文件时)。我本来以为计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | INTEGER_SIZE=4 fid=open('hello_python.test','rb') ### FIRST WAY I ORIGINALLY READ THE DATA ### # This works, but I figured I would try hard coding the size # so the uncommented version is what I am currently using. # # first_data=struct.unpack('>i',fid.read(struct.calcsize('>i')))[0] # second_data=struct.unpack('>i',fid.read(struct.calcsize('>i')))[0] ### HOW I READ DATA CURRENTLY ### first_data=struct.unpack('>i',fid.read(INTEGER_SIZE))[0] second_data=struct.unpack('>i',fid.read(INTEGER_SIZE))[0] print"first data: '%d'" % first_data print"second data: '%d'" % second_data fid.close() >> first data: 8 >> second data: 1 |
现在,假设我想在MATLAB中阅读
1 2 | >> first data: 419430400 >> second data: 16777216 |
这很奇怪,所以我做了相反的事情。我看了看
1 2 | >> first data: 419430400 >> second data: 16777216 |
因此,发生了一些奇怪的事情,但我不知道这是什么。还要注意,尽管这是一个较大项目的一部分,但我只是将代码的这些部分提取到一个新项目中,并使用这些结果测试了上面的示例。我真的很困惑如何使该文件可移植:(任何帮助将不胜感激。
问题在于字节顺序,即数字中的位顺序。您必须在x86或x86-64计算机上(因为这是MATLAB唯一支持的计算机),并且它们是低端字节序的。但是,python
如果您只打算在x86或x86-64计算机上使用Python代码,或者只考虑在同一台计算机上在MATLAB和Python之间发送数据,则可以完全不使用字节顺序标记并使用本机字节顺序(所以
对于此示例,这似乎是唯一的问题。我想指出的是,如果您尝试一次读写数据的数组/矩阵,那么
您可能对熊猫hdf5商店感兴趣:
在Python中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 In [418]: df_for_r = pd.DataFrame({"first": np.random.rand(100),
.....: "second": np.random.rand(100),
.....: "class": np.random.randint(0, 2, (100,))},
.....: index=range(100))
.....:
In [419]: df_for_r.head()
Out[419]:
class first second
0 0 0.417022 0.326645
1 0 0.720324 0.527058
2 1 0.000114 0.885942
3 1 0.302333 0.357270
4 1 0.146756 0.908535
In [420]: store_export = HDFStore('export.h5')
In [421]: store_export.append('df_for_r', df_for_r)
In [422]: store_export
Out[422]:
<class 'pandas.io.pytables.HDFStore'>
File path: export.h5
/df_for_r frame_table (typ->appendable,nrows->100,ncols->3,indexers->[index])
在Matlab中:
1 | data = h5read('export.h5','/df_for_r'); |
但是我不确定它是否有效,完全在浏览器中编写了...