【debug记录】MATLAB内置reshape与Python NumPy库reshape的差异
- 背景
- 函数原型
- MATLAB内置reshape
- NumPy库reshape
- 差异分析
- 解决方法
背景
最近在编程时遇到一个需求,需要将MATLAB工具箱中的函数用Python NumPy库进行实现,在对实现进行验证的过程中,遇到输入相同,但MATLAB和NumPy的计算输出不一致的问题。
排除计算精度问题后,经过多次debug发现,这是由于MATLAB内置reshape与NumPy库reshape的默认操作方向不同。
函数原型
MATLAB内置reshape
MATLAB内置reshape的函数原型为1:
B = reshape(A,sz)
B = reshape(A,sz1,...,szN)
输入:
A
:待重构的数组,可以是向量、矩阵或多维数组等。
sz
:输出大小,是一个由整数组成的行向量。
sz1,...,szN
:每个维度的大小,必须是整数。
输出:
B
:重构的数组,数据类型和元素数与输入A
中的数据类型和元素数相同。
NumPy库reshape
NumPy库reshape的函数原型为2:
b = numpy.reshape(a, shape=None, order='C', newshape=None, copy=None)
输入:
a
:待重构的数组,ndarray类型。
shape
:输出大小,是一个int或int元组。如果是int,则重构的数组将是该shape的一维数组。一个shape的维度可以是-1。在这种情况下,shape的值是根据数组的长度和剩余维度推断出来的。
order
:可选参数,通过字符集{‘C’, ‘F’, ‘A’}中的任一字符指定reshape操作的顺序,默认值为’C’。
可选字符 | 含义 |
---|---|
‘C’ | 使用类似C语言的索引顺序读取/写入元素 |
‘F’ | 使用类似Fortran语言的索引顺序读取/写入元素 |
‘A’ | 如果a 在内存中是类似Fortran语言连续的,则以类似Fortran语言的索引顺序读取/写入元素,否则以类似C语言的顺序 |
newshape
:自2.1版起已弃用,由shape参数替代。保留以保持向后兼容。
copy
:可选参数,布尔类型,默认值为None。
可选值 | 含义 |
---|---|
True | 数组数据进行复制 |
None | 仅在order 参数设置中被需要时,才会进行复制 |
False | 数组数据不会进行复制,但可能在数组数据必须被复制时引发错误 |
输出:
b
:重构的数组,数据类型和元素数与输入a
中的数据类型和元素数相同。
差异分析
在默认情况下,即NumPy库reshape函数的order
参数为'C'
时,reshape操作使用的是行主序,这意味着在多维数组中,元素是按行来存储的,因此NumPy是根据行的方向进行reshape操作。
同样在默认情况下,MATLAB内置reshape操作使用的是列主序,即MATLAB是根据列的方向进行reshape操作。
具体地,以一个行向量数据[1, 2, 3, 4]
为例,将其reshape成(2, 2)
的形状。NumPy库reshape会优先考虑在行方向上填充内容,即[1, 2]
作为第一行,剩下的[3, 4]
作为第二行,最终reshape结果为[[1, 2], [3, 4]]
;MATLAB内置reshape优先考虑在列方向上填充内容,即[1, 2]
作为第一列,剩下的[3, 4]
作为第二列,最终reshape结果为[[1, 3], [2, 4]]
。
解决方法
基于上述内容,由于MATLAB内置reshape没有提供操作方向的可选参数,如果需要NumPy库的reshape与MATLAB内置reshape的输出一致,那么可修改NumPy库reshape的操作方向,使其与MATLAB内置reshape操作方向一致,即将NumPy库reshape的参数order
设置为'F'
。
MATLAB reshape帮助文档 ↩︎
NumPy reshape文档 ↩︎