【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文档 ↩︎