使用 python 和 matlab 写入二进制文件的不同结果

Different result writing to binary file with python and matlab

我正在尝试将 matlab 脚本转换为 python。该脚本涉及将数据写入二进制文件。我注意到文件之间的差异,特别是在编写 matrices/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结果(如记事本所示):

ð? @@@

由于记事本尝试将整数读取为文本的方式,字符看起来仍然非常相似,但我认为它提供了足够的提示。为了方便打字,我们把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 顺序是默认的。