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,这样你就知道你搞砸了某个地方.
祝好运!
基于 @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)