在Matlab排序中从numpy数组中顺序获取数据

vau*_*ech 3 python matlab numpy

举个例子,在Matlab中假设一个a(2,3,2)像这样的矩阵:

a(:,:,1) =

     1     2     3
     4     5     6


a(:,:,2) =

     7     8     9
    10    11    12
Run Code Online (Sandbox Code Playgroud)

如果我mex按顺序使用和访问此矩阵的元素,我会得到以下顺序(最后,顺序访问它们的代码):

1, 4, 2, 5, 3, 6, 7, 10, 8, 11, 9, 12
Run Code Online (Sandbox Code Playgroud)

现在,如果我在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]]])
Run Code Online (Sandbox Code Playgroud)

,我可以尝试使用.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])
Run Code Online (Sandbox Code Playgroud)

有没有一种优雅的方式来访问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 }
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 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
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

让我们尝试关联3D这两个环境中问题中列出的数组案例的这些维度和轴术语:

MATLAB      NumPy
------------------
cols        axis-1
rows        axis-2
dim3        axis-0
Run Code Online (Sandbox Code Playgroud)

因此,为了模拟NumPy中与MATLAB相同的行为,我们需要NumPy中的轴为:(1,2,0).与NumPy的存储元素的方式一起,从最后一个轴开始到第一个轴,即以相反的顺序存储,所需的轴顺序将是(0,2,1).

要以这种方式执行轴的置换,我们可以使用np.transpose并随后使用扁平化操作np.ravel() -

a.transpose(0,2,1).ravel()
Run Code Online (Sandbox Code Playgroud)

样品运行 -

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])
Run Code Online (Sandbox Code Playgroud)