Matlab有两个函数用于将矩阵下标转换为线性索引,反之亦然。 (ind2sub和sub2ind)
我找到了R的等价物,但在Python中有相同的方法吗?
答案 0 :(得分:20)
Google搜索引导我访问此链接:https://github.com/jjakeman/pyheat/blob/master/utilities/math_utils.py
据我所知,MATLAB中没有直接实现这些函数。
事实证明我无法正确阅读文档。如果您想要sub2ind
的功能,则需要ravel_multi_index
功能。函数声明表明您需要两个输入。第一个输入是2D numpy
数组,其中每一行都是特定维度的位置。例如,如果要在2D矩阵上应用ind2sub
,则应指定2D numpy
数组,其中第一行包含所需的所有行位置,第二行包含所有行位置您想要的列位置。第二个输入是确定每个维度大小的元组,因此对于2D数组,它是行数和列数。
要执行ind2sub
,您需要unravel_index
功能。第一个输入是一个线性索引数组,您希望将其转换为数组中每个维度的位置。第二个输入是像以前一样的维度元组。
如果您想尝试自己实施这些内容,我将把帖子留在底层,以备后人使用。
但是,你当然可以自己实现这些。我假设是因为您使用numpy
标记了帖子,您需要numpy
- esque解决方案。请记住,在numpy
中您可以访问行主要元素,而不是列主要元素,因此给定两个数组,其中一个用于行,另一个用于列索引(0索引),2D矩阵的sub2ind
非常简单:
def sub2ind(array_shape, rows, cols):
return rows*array_shape[1] + cols
array_shape
是一个包含两个元素的数组,其中第一个元素是矩阵中的行数,第二个元素是列数。如果您还记得,可以通过以下方式访问行主矩阵中的元素:
ind = r*cols + c
(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)
这里,输出是一个双元素元组,其中第一个元素是行位置,第二个元素是列位置。要总结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)
我做了一些基本的错误检查,以确保sub2ind
的行或列或ind2sub
的线性索引没有超出范围。我将这些位置设置为-1,这样你就知道你搞砸了某个地方。
答案 1 :(得分:8)
答案 2 :(得分:3)
在@rayryeng和@ theblackcat的答案的基础上,你还应该注意到你将不得不使用Fortran样式索引,并且回想起Python被索引为0而MATLAB是1索引。
Fortran风格的要求让我感到有些困惑。
在Python中:
np.unravel_index(7, [1, 2, 3, 4], 'F')
(0, 1, 0, 1)
并在MATLAB / Octave中
[a, b, c, d] = ind2sub([1, 2, 3, 4], 8)
a = 1
b = 2
c = 1
d = 2
答案 3 :(得分:0)
对于2D矩阵,可以使用Python内置的proc = subprocess.Popen(["ip -o -6 addr list | awk '{{print $4}}' | cut -d/ -f1"], stdout=subprocess.PIPE, shell=True)
ipv6_all = proc.communicate()[0]
函数(返回除数的商和余数)。要获取divmod
矩阵的下标(r,c)
,请使用:
nrows x ncols
用于行优先排序
(r, c) = divmod(ind, ncols)
用于列的主要排序
例如,按行优先(C风格)的3x6矩阵:
(c, r) = divmod(ind, nrows)
0 1 2 3 4 5
(0,0) (0,1) (0,2) (0,3) (0,4) (0,5)
6 7 8 9 10 11
(1,0) (1,1) (1,2) (1,3) (1,4) (1,5)
12 13 14 15 16 17
(2,0) (2,1) (2,2) (2,3) (2,4) (2,5)
3x6矩阵,按列优先(Fortran样式)排序:
(0, 0) = divmod(0, 6)
(0, 3) = divmod(3, 6)
(1, 0) = divmod(6, 6)
(1, 5) = divmod(11, 6)
(2, 2) = divmod(14, 6)
0 3 6 9 12 15
(0,0) (0,1) (0,2) (0,3) (0,4) (0,5)
1 4 7 10 13 16
(1,0) (1,1) (1,2) (1,3) (1,4) (1,5)
2 5 8 11 14 17
(2,0) (2,1) (2,2) (2,3) (2,4) (2,5)