MATLAB中的ind2sub相当于Python

Dat*_*aTx 11 python matlab numpy

Matlab有两个函数用于将矩阵下标转换为线性索引,反之亦然.(ind2sub和sub2ind)

我找到了R的等价物,但在Python中有相同的方法吗?

ray*_*ica 21

谷歌搜索引导我到这个链接:https://github.com/jjakeman/pyheat/blob/master/utilities/math_utils.py

据我所知,在MATLAB中没有直接实现这些功能.


事实证明我无法正确阅读文档.如果你想要的功能sub2ind,你会想要这个ravel_multi_index功能.函数声明表明您需要两个输入.第一个输入是2D numpy数组,其中每一行是特定维度的位置.例如,如果要应用于ind2sub2D矩阵,则应指定一个2D numpy数组,其中第一行包含所需的所有行位置,第二行包含所需的所有列位置.第二个输入是确定每个维度大小的元组,因此对于2D数组,它是行数和列数.

要做ind2sub,你想要的unravel_index功能.第一个输入是一个线性索引数组,您希望将其转换为数组中每个维度的位置.第二个输入是像以前一样的维度元组.

如果你想尝试自己实现这些,我将把底部的帖子留给后人.


但是,您当然可以自己实现这些.我假设这是因为你用你的标签标记你numpy需要一个numpy- 解决方案.请记住,在numpy您访问主要元素而不是主要元素时,因此给定两个数组,一个用于行,另一个用于列索引(0索引),sub2ind对于2D矩阵非常简单:

def sub2ind(array_shape, rows, cols):
    return rows*array_shape[1] + cols
Run Code Online (Sandbox Code Playgroud)

array_shape是一个包含两个元素的数组,其中第一个元素是矩阵中的行数,第二个元素是列数.如果您还记得,您可以通过以下方式访问行主矩阵中的元素:

ind = r*cols + c
Run Code Online (Sandbox Code Playgroud)

(r,c)是你想要的行和列索引,前提是它是0索引的.换句话说,你会使用整数除法和模数:

def ind2sub(array_shape, ind):
    rows = (ind.astype('int') / array_shape[1])
    cols = (ind.astype('int') % array_shape[1]) # or numpy.mod(ind.astype('int'), array_shape[1])
    return (rows, cols)
Run Code Online (Sandbox Code Playgroud)

这里,输出是一个双元素元组,其中第一个元素是行位置,第二个元素是列位置.总而言之ind2sub,要访问所需的行,可以使用线性索引并对列进行整数除法.要获得所需的列,可以找到模数或余数.进入3个维度以及之后会有点复杂.我将让您看看上面提到的链接以获取更多详细信息.

显然,我没有在上述函数中进行任何错误检查,所以array_shape在这种情况下你显然会利用它.做你想做的更好的方法是:

def sub2ind(array_shape, rows, cols):
    ind = rows*array_shape[1] + cols
    ind[ind < 0] = -1
    ind[ind >= array_shape[0]*array_shape[1]] = -1
    return ind

def ind2sub(array_shape, ind):
    ind[ind < 0] = -1
    ind[ind >= array_shape[0]*array_shape[1]] = -1
    rows = (ind.astype('int') / array_shape[1])
    cols = ind % array_shape[1]
    return (rows, cols)
Run Code Online (Sandbox Code Playgroud)

我做了一些基本的错误检查,以确保没有行或列sub2ind或线性索引ind2sub超出范围.我将这些位置设置为-1,这样你就知道你搞砸了某个地方.

祝好运!

  • 我希望官方文档也是这样写的。 (2认同)

Gil*_*lly 6

基于 @rayryeng 和 @theblackcat 的答案,您还应该注意,您必须使用 Fortran 样式索引,并记住 Python 是 0 索引,而 MATLAB 是 1 索引。

Fortran 风格要求让我有点迷惑。

在Python中:

np.unravel_index(7, [1, 2, 3, 4], 'F')
(0, 1, 0, 1)
Run Code Online (Sandbox Code Playgroud)

以及在 MATLAB/Octave 中

[a, b, c, d] = ind2sub([1, 2, 3, 4], 8)
a =  1
b =  2
c =  1
d =  2
Run Code Online (Sandbox Code Playgroud)