【问题标题】:Different result writing to binary file with python and matlab使用 python 和 matlab 写入二进制文件的不同结果
【发布时间】:2021-08-28 00:07:03
【问题描述】:

我正在尝试将 matlab 脚本转换为 python。该脚本涉及将数据写入二进制文件。我注意到文件之间的差异,特别是在编写矩阵/numpy 数组时。在编写其他变量类型(int、string 等)时,文件与所需的相同。

Matlab 代码:

fid = fopen("test2.txt", "wb");
a = [[1 2];[3 4]];
fwrite(fid, a, "float64");
fclose(fid);

matlab结果(如记事本所示):

ð? @@@

Python 代码:

import numpy as np
with open("test2.txt", "wb") as fid:
    a = np.array([[1, 2], [3, 4]])
    fid.write(a.astype("float64"))
    # a.astype("float64").tofile(fid) # also doesn't give correct result

Python结果(如记事本所示):

ð? @@@

【问题讨论】:

  • 你发布的结果和我一模一样,你能指出区别吗?
  • @BatWannaBe 看起来 SO 去除了显示差异的字符(正方形)。添加了显示差异的屏幕截图。
  • 您的 NumPy 和 MATLAB 矩阵不一样,它们是彼此的转置版本。因此,它们以不同的顺序写入文件。
  • 还要注意,在MATLAB中,a = [[1 2];[3 4]];有很多多余的括号,最好写成a = [1 2; 3 4];
  • 我不认为它们是相互转换的版本。为了证实这一点,a = [1 2 3; 4 5 6];和 a = np.array([[1, 2, 3], [4, 5, 6]]) 给出相同的大小/形状,但在二进制文件中显示不同。

标签: python numpy matlab binaryfiles


【解决方案1】:

由于记事本试图将整数作为文本读取,字符看起来仍然非常相似,但我认为它提供了足够的提示。为了便于打字,我们将 Matlab 的文本称为 d? [@ _@ [@ 和 Python 的文本称为 d? _@ [@ [@

计算机内存是线性的,因此所有多维数组实际上都存储为一维数组。您看到的是 NumPy 数组是 C 顺序(默认情况下),而 Matlab 矩阵是 Fortran 顺序(默认情况下)。这个顺序是多维数组在内存中被展平为一维数组的方式。

matrix   notepad text
1  2     d?  _@               
3  4     [@  [@

Matlab Fortran order goes by columns
 1  3  2  4
d? [@ _@ [@

NumPy C order goes by rows
 1  2  3  4
d? _@ [@ [@

由于您是在 MATLAB 和 Python 之间转换代码,因此您应该非常清楚数组顺序的不同。当您不在内存中跳转时迭代会更快,因此嵌套的 for 循环可能必须重新排序。它不会对矢量化代码 someScalar * myArray 产生太大影响,因为它是为您处理的。 NumPy 确实提供了函数和可选参数来创建 Fortran 顺序数组 numpy.asfortranarray(), ndarray.copy(order = 'F') 并检查顺序 ndarray.flags.f_contiguous, ndarray.flags.c_contiguous,但使用它进行编码仍然更加困难,因为 C 顺序是默认设置。

【讨论】:

  • 我能够使用a.T.astype("float64").tofile(fid) 获得正确的输出,但fid.write(a.T.astype("float64") 导致 ValueError: ndarray is not C-contiguous
  • 我不确定使用 Python 的 open 保存二进制文件是否适合这里。我相信您可以弄清楚如何使它工作,但是 NumPy 提供 numpy.save/.npy 文件和 MATLAB 提供 save/.mat 文件是有原因的。我不使用 MATLAB,所以我不能告诉你 MATLAB 是否有类似的东西,但是基于 NumPy 构建的 SciPy 实际上提供了一种处理 .mat 文件的方法:scipy.io.savemat, scipy.io.loadmat, scipy.io.whosmat
  • 我正在转换的 MATLAB 脚本用于创建有限元模型文件(具有规定格式/数据布局),因此无法使用 .mat 或 .npy。有了你的解释,我已经能够解决我的问题了。
猜你喜欢
  • 1970-01-01
  • 2020-05-31
  • 2015-04-26
  • 2010-09-17
  • 2014-01-07
  • 1970-01-01
  • 2011-08-06
  • 2013-08-18
  • 2011-02-04
相关资源
最近更新 更多