首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从Python解析用MATLAB编写的二进制文件,反之亦然

从Python解析用MATLAB编写的二进制文件,反之亦然
EN

Stack Overflow用户
提问于 2016-08-21 01:03:06
回答 2查看 1.9K关注 0票数 0

我在python中的struct.unpack遇到了很大的麻烦。我有一个预置格式的二进制文件,可以用MATLAB编写,也可以用Python编写。

我可以用Python将二进制数据写到文件中,并且没有任何问题地将数据读取回来。我也可以将相同的数据从MATLAB写入二进制文件,并在MATLAB中读取它,没有问题。

当我用MATLAB编写数据并尝试用Python读取数据时,或者当我用Python编写数据并试图用MATLAB读取数据时,我的问题就来了。

为了简单起见,假设我正在将两个整数写入一个二进制文件(大端文件)。每个整数是4个字节。第一个整数是不大于4个字节的有效整数,第二个整数必须等于1、2或3。

首先,下面是我如何用MATLAB编写数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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里读到的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fid=fopen('hello_matlab.test','rb');
first_data=fread(fid,1,'int');
second_data=fread(fid,1,'int');

fprintf('first data: %d\n', first_data);
fprintf('second data: %d\n', second_data);

fclose(fid);

    >> first data: 8
    >> second data: 1

下面是我如何用Python编写数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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编写的文件时)。我一开始以为计算struct.calcsize('>i')的方式有些奇怪,所以我删除了它,而是添加了一个硬编码常量INTEGER_SIZE,以表示我知道MATLAB在编码它时使用的字节数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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中阅读hello_python.test。使用我当前的MATLAB代码,下面是新的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>> first data: 419430400
>> second data: 16777216

这很奇怪,所以我做了相反的事情。我看了看当我读hello_matlab.test时发生了什么。对于我当前的Python代码,下面是新的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>> first data: 419430400
>> second data: 16777216

所以,有些奇怪的事情正在发生,但我不知道它是什么。还请注意,虽然这是一个较大项目的一部分,但我确实将代码的这些部分提取到一个新项目中,并使用这些结果测试了上面的示例。我真的很困惑如何使这个文件可移植:(任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-21 07:07:17

问题在于痴呆症,一个数字中位的顺序。您必须在x86或x86-64计算机上(因为这些计算机是MATLAB唯一支持的),而这些计算机是小endian。然而,python >i告诉它使用大端字节顺序。所以你用的是相反的字节顺序,这使得这两种语言读出来的数字完全不同。

如果您只计划在x86或x86-64计算机上使用Python代码,或者只关心在同一台计算机上在MATLAB和Python之间发送数据,那么您可以完全取消字节顺序标记,使用本机字节顺序(所以是i而不是>i)。如果您可能正在powerpc系统上的python上运行,您可能需要手动-指定小-endianess (<i)。

在这个例子中,这似乎是唯一的问题。我想指出的是,如果您尝试一次读写数组/数据矩阵,那么numpy.fromfile将更快、更容易。

票数 1
EN

Stack Overflow用户

发布于 2016-08-21 01:28:52

你可能会在熊猫hdf5商店里闲逛:

在Python中:

在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)) .在419: df_for_r.head() Out419:第二级0 0.417022 0.326645 1 0 0.720324 0.527058 2 0.000114 0.885942 3 0.302333 0.357270 4 0.146756 0.908535 In 420: store_export = HDFStore('export.h5 ))在421: store_export.append('df_for_r',( df_for_r)在422: store_export Out422:文件路径: export.h5 /df_for_r frame_table (类型->附录,nrows>100,ncols->3,索引器->索引)

在matlab中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
data = h5read('export.h5','/df_for_r');

但我不确定它是否有效,完全用浏览器写的.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39062570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文