【问题标题】:Get data sequentially from numpy array in Matlab ordering从Matlab排序中的numpy数组顺序获取数据
【发布时间】:2017-01-06 14:05:10
【问题描述】:

例如,假设在 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 }

【问题讨论】:

  • 所以你在 numpy 中的矩阵不等于你在 MATLAB 中的矩阵。检查你的 numpy 数组的形状。
  • 哦...你是对的。它是 (2, 2, 3)。

标签: python matlab numpy


【解决方案1】:

这让很多从 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

在 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])

【讨论】:

  • 谢谢。这行得通。从来没有想过这会这么容易。我花了半天时间试图了解发生了什么。 Matlab 和 numpy 打印其输出的方式具有误导性(让我认为这两个矩阵是相同的)。
  • 既然你做的很完整,我想问一下(我测试了这个案例,它似乎有效,但我不确定):如果Matlab中的size(a)与@987654336相同@ 在 Numpy 中,然后 a.ravel() 通常会给我相同的顺序? (这完全不是我的预期)
  • @vaulttech 相同的形状并不能保证扁平版本(没有任何轴排列)是相同的。这就是这个答案帖子的重点。使用ravel() 进行的展平操作(基本上是在答案帖子中使用的ravel('C'))对置换/转置数组进行操作并展平。对于2D 的情况,它将是a.transpose(0,1).ravel() 或简单的.ravel('F')。对于4D 的情况,它会有所不同,依此类推。这能回答你的问题吗?
  • 确实如此。我把它弄糊涂了,因为我的例子中有两个尺寸为“2”的尺寸。我只需要稍微思考一下就可以消化这一点。谢谢。
【解决方案2】:

这是对@Divakar's 答案的补充。

在 Octave 中,我制作了 xa 并将它们保存到一个文件中

>> 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 订单为“F”显示原始平面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,它产生一个顺序为'C'的(4,3,2)数组:

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.]]

【讨论】:

    猜你喜欢
    • 2015-07-17
    • 2021-08-09
    • 2020-02-16
    • 2013-06-26
    • 2019-03-19
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 2021-09-23
    相关资源
    最近更新 更多