【问题标题】:How to get the linear index for a numpy array (sub2ind)如何获取 numpy 数组的线性索引(sub2ind)
【发布时间】:2013-03-05 17:22:05
【问题描述】:

Matlab 提供了函数sub2ind,它“返回线性索引等价于行和列下标......对于矩阵......”

我需要这个 sub2ind 函数或类似的东西,但我没有找到任何类似的 Python 或 Numpy 函数。如何获得此功能?

这是来自matlab documentation 的示例(与上面相同的页面):

Example 1

This example converts the subscripts (2, 1, 2) for three-dimensional array A 
to a single linear index. Start by creating a 3-by-4-by-2 array A:

rng(0,'twister');   % Initialize random number generator.
A = rand(3, 4, 2)

A(:,:,1) =
    0.8147    0.9134    0.2785    0.9649
    0.9058    0.6324    0.5469    0.1576
    0.1270    0.0975    0.9575    0.9706
A(:,:,2) =
    0.9572    0.1419    0.7922    0.0357
    0.4854    0.4218    0.9595    0.8491
    0.8003    0.9157    0.6557    0.9340

Find the linear index corresponding to (2, 1, 2):

linearInd = sub2ind(size(A), 2, 1, 2)
linearInd =
    14
Make sure that these agree:

A(2, 1, 2)            A(14)
ans =                 and =
     0.4854               0.4854

【问题讨论】:

    标签: matlab numpy


    【解决方案1】:

    我想你想使用np.ravel_multi_index。使用 numpy 的基于零的索引,并考虑到 matlab 数组是 Fortran 风格,相当于您的 matlab 示例是:

    >>> np.ravel_multi_index((1, 0, 1), dims=(3, 4, 2), order='F')
    13
    

    只是为了让您了解发生了什么,您可以使用索引的点积和数组的步幅得到相同的结果:

    >>> a = np.random.rand(3, 4, 2)
    >>> np.dot((1, 0, 1), a.strides) / a.itemsize
    9.0
    >>> np.ravel_multi_index((1, 0, 1), dims=(3, 4, 2), order='C')
    9
    >>> a[1, 0, 1]
    0.26735433071594039
    >>> a.ravel()[9]
    0.26735433071594039
    

    【讨论】:

    • 这有点误导。这使得您看起来需要知道数组的内存布局才能使用平面索引,这是不正确的。 strides 方法仅适用于 C-Contiguous 数组,而这始终是正确的:A[idx] == A.flat[flat_idx] == A.ravel()[flat_idx] 如果flat_idx = np.ravel_multi_index(idx, A.shape)。值得注意的是,flat_idx 在 matlab 和 numpy 中的计算方式不同。
    【解决方案2】:

    这就是我为我解决问题的方法,重写为类似于上面给出的示例。

    主要思想是使用arangereshape 的索引创建一个辅助数组。

    In [1]: import numpy as np
    
    In [2]: A = np.random.rand(3,4,2)
    
    In [3]: A
    Out[3]: 
    array([[[ 0.79341698,  0.55131024],
            [ 0.29294586,  0.22209375],
            [ 0.11514749,  0.15150307],
            [ 0.71399288,  0.11229617]],
    
           [[ 0.74384776,  0.96777714],
            [ 0.1122338 ,  0.23915265],
            [ 0.28324322,  0.7536933 ],
            [ 0.29788946,  0.54770654]],
    
           [[ 0.13496253,  0.24959013],
            [ 0.36350264,  0.00438861],
            [ 0.77178808,  0.66411135],
            [ 0.26756112,  0.54042292]]])
    
    In [4]: helper = np.arange(3*4*2)
    
    In [5]: helper
    Out[5]: 
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
           17, 18, 19, 20, 21, 22, 23])
    
    In [6]: helper = helper.reshape([3,4,2])
    
    In [7]: helper
    Out[7]: 
    array([[[ 0,  1],
            [ 2,  3],
            [ 4,  5],
            [ 6,  7]],
    
           [[ 8,  9],
            [10, 11],
            [12, 13],
            [14, 15]],
    
           [[16, 17],
            [18, 19],
            [20, 21],
            [22, 23]]])
    
    In [8]: linear_index = helper[1,0,1]
    
    In [9]: linear_index
    Out[9]: 9
    

    请注意:

    • 行和列在 Numpy 中切换到 Matlab。
    • Matlab 以 1 开头索引,Python 和 Numpy 以 0 开头。

    【讨论】:

      猜你喜欢
      • 2023-04-05
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 2021-03-10
      • 2019-09-16
      • 2018-09-01
      相关资源
      最近更新 更多