Matlab与Python/Numpy高维矩阵线性索引顺序的区别
这里我将在介绍索引顺序之前介绍一下创建矩阵,因为这里也是利用的线性索引,有助于理解后面的索引顺序。
创建矩阵
同样是创建从1到60的3×4×5的三维矩阵,可以从下面这个简单的例子中一窥两者的区别,大家可以体会一下。为了方便观察,三维图只展示了落在三个平面上的数字,但应该已经足够理解了。
Numpy:
import numpy as np
a=np.arange(1,61).reshape(3,4,5)
我们可以看到,Numpy是按照z-y-x的顺序填充元素的,想象比作把元素向矩阵容器里塞,每个z轴是一根管子,那就是在塞满a[0,0,:]后,接着去塞a[0,1,:],到第二维被塞满后才去塞a[1,0,:]。
Matlab:
b=reshape(1:60,[3,4,5])
Matlab的填充方式则恰恰相反,在将最低维“塞满”后,才开始向高维叠加。
布尔索引
接下来展示两者进行布尔索引的时候的不同,为了保持一致性,均使用之前由Matlab创建的矩阵来索引,Python中的矩阵由Matlab中读取而来:
save('test.mat',b)
from scipy.io import loadmat
b = loadmat('test.mat')['b']
Numpy:
b[b%5==0]
对比前面的三维图可以看出,Numpy索引元素的顺序依然是按照其创建矩阵时的顺序来列出索引的。
此外如果将Numpy的整个矩阵打印到终端,还可以看到,越内侧的方括号维数越高,下面是b[0,:,:],即上面第二张图的y-z面:
Matlab:
b(rem(b,5)==0) % 列出可以被5整除的元素的线性索引
由于是拿Matlab创建的矩阵索引,所以顺序和创建时的大小顺序一致。
总结
Matlab创建和索引矩阵时是以最低维开始,逐步向高维叠加,符合人类直觉。而Numpy则相反,是从最高维开始索引。