作为一个例子,假设在Matlab中,像这样的矩阵a(2,3,2)
:
a(:,:,1) =
1 2 3
4 5 6
a(:,:,2) =
7 8 9
10 11 12
如果我使用mex
并按顺序访问此矩阵的元素,我会得到以下顺序(最后,顺序访问它们的代码):
1, 4, 2, 5, 3, 6, 7, 10, 8, 11, 9, 12
现在,如果我在numpy中有相同的矩阵
In [2]: np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
Out[2]:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
,我可以尝试使用.flatten(...)
按顺序访问项目(无法找到更好的方法 - 我愿意接受建议)。 flatten()
有4"命令"选项:
In [4]: a.flatten('F')
Out[4]: array([ 1, 7, 4, 10, 2, 8, 5, 11, 3, 9, 6, 12])
In [5]: a.flatten('C')
Out[5]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
In [6]: a.flatten('A')
Out[6]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
In [7]: a.flatten('K')
Out[7]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
在Matlab排序中是否有一种优雅的方式来访问numpy数组的元素? (在我的实际使用案例中,这些矩阵很大,因此将它们复制在一起并不是首选)
[不太好,我知道,只是为了测试]
1 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
2 {
3 // This just a test: hardcoding the size of `data_input`
4 int data_input_size = 12;
5 double *data_input;
6 const mxArray *batch_data;
7
8 // Gets a pointer to the first element of batch_data
9 data_input = mxGetPr(prhs[0]);
10
11 for(int i = 0; i < data_input_size; i++) {
12 printf("working_data[i]: %f\n", data_input[i]);
13 }
14 plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
15 }
答案 0 :(得分:6)
这会让很多人从MATLAB进入NumPy / Python。因此,在MATLAB中,索引格式为(column x row x dim3)
,依此类推。使用NumPy,它是(axis-0, axis-1, axis-2)
,依此类推。
使用MATLAB上的示例案例示意性地显示:
>> a = reshape(1:27,[3,3,3]);
>> a
a(:,:,1) =
row
--------------->
1 4 7 | |
2 5 8 | col |
3 6 9 v |
a(:,:,2) = |
10 13 16 | dim3
11 14 17 |
12 15 18 |
a(:,:,3) = |
19 22 25 |
20 23 26 |
21 24 27 v
On NumPy:
In [62]: a = np.arange(27).reshape(3,3,3)
In [63]: a
Out[63]:
axis=2
---------->
array([[[ 0, 1, 2], | |
[ 3, 4, 5], | axis=1 |
[ 6, 7, 8]], v |
|
[[ 9, 10, 11], |
[12, 13, 14], | axis=0
[15, 16, 17]], |
|
[[18, 19, 20], |
[21, 22, 23], |
[24, 25, 26]]]) v
让我们尝试关联这两个环境之间问题中列出的3D
数组案例的维度和轴术语:
MATLAB NumPy
------------------
cols axis-1
rows axis-2
dim3 axis-0
因此,为了模拟NumPy中与MATLAB相同的行为,我们需要NumPy中的轴为:(1,2,0)
。与NumPy一样,从最后一个轴开始存储元素到第一个轴的方式,即按相反的顺序,所需的轴顺序为(0,2,1)
。
要以这种方式执行轴的置换,我们可以使用np.transpose
,然后使用np.ravel()
-
a.transpose(0,2,1).ravel()
示例运行 -
In [515]: a
Out[515]:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
In [516]: a.transpose(0,2,1) # Permute axes
Out[516]:
array([[[ 1, 4],
[ 2, 5],
[ 3, 6]],
[[ 7, 10],
[ 8, 11],
[ 9, 12]]])
In [517]: a.transpose(0,2,1).ravel() # Flattened array
Out[517]: array([ 1, 4, 2, 5, 3, 6, 7, 10, 8, 11, 9, 12])
答案 1 :(得分:2)
这是@Divakar's
回答的补充。
在Octave中,我制作了x
和a
并将其保存到文件
>> x=[1, 4, 2, 5, 3, 6, 7, 10, 8, 11, 9, 12]
>> a=reshape(x,2,3,2)
a =
ans(:,:,1) =
1 2 3
4 5 6
ans(:,:,2) =
7 8 9
10 11 12
我可以使{与a
相同)展开mex
:
>> a(:).'
numpy,来自loadmat
scipy.io
In [564]: data = loadmat('test.mat')
In [566]: data['x']
Out[566]:
array([[ 1., 4., 2., 5., 3., 6., 7., 10., 8., 11., 9.,
12.]])
In [567]: data['a']
Out[567]:
array([[[ 1., 7.],
[ 2., 8.],
[ 3., 9.]],
[[ 4., 10.],
[ 5., 11.],
[ 6., 12.]]])
ravel
订单&#39; F&#39;显示原始广告x
:
In [571]: data['a'].ravel(order='F')
Out[571]:
array([ 1., 4., 2., 5., 3., 6., 7., 10., 8., 11., 9., 12.])
为了帮助跟踪形状,我更喜欢使它们变得不同。例如
>> x=0:23;
>> a=reshape(x,2,3,4);
和a
显示为
ans(:,:,1) =
0 2 4
1 3 5
...
ans(:,:,4) =
18 20 22
19 21 23
显示4(2,3)个矩阵。
在numpy方面,我得到:
In [575]: data['a'].shape
Out[575]: (2, 3, 4)
In [577]: data['a']
Out[577]:
array([[[ 0., 6., 12., 18.],
[ 2., 8., 14., 20.],
[ 4., 10., 16., 22.]],
[[ 1., 7., 13., 19.],
[ 3., 9., 15., 21.],
[ 5., 11., 17., 23.]]])
这是2块(3,4)形状。
In [579]: data['a'].ravel('F')
Out[579]:
array([ 0., 1., 2., 3., 4., 5., ..., 23.])
我看到numpy和MATLAB / Octave之间的两个关键区别。默认顺序不同,但numpy
允许您指定F
。 3d(和更大)数组的显示是不同的。实际上有一种不同的“飞机”概念。或块。
np.transpose
更改数组的形状,步幅和顺序,同时保持相同的数据库。
应用于a
,它会生成一个带有顺序的(4,3,2)数组&#39; C&#39;:
In [580]: data['a'].T
Out[580]:
array([[[ 0., 1.],
[ 2., 3.],
[ 4., 5.]],
....
[[ 18., 19.],
[ 20., 21.],
[ 22., 23.]]])
In [581]: data['a'].T.ravel()
Out[581]:
array([ 0., 1., 2., 3., ...22., 23.])
MATLAB显示可以复制:
In [584]: for i in range(4):
...: print(data['a'][:,:,i])
...:
[[ 0. 2. 4.]
[ 1. 3. 5.]]
[[ 6. 8. 10.]
[ 7. 9. 11.]]
[[ 12. 14. 16.]
[ 13. 15. 17.]]
[[ 18. 20. 22.]
[ 19. 21. 23.]]