我已经阅读了np.unravel_index的文档,并尝试了一下这个函数,但我不知道它在做什么。
np.unravel_index
ulydmbyx1#
计算机内存是线性寻址的。每个存储器单元对应于一个数字。一个内存块可以用一个基址和一个项索引来寻址,基址是它的第一个元素的内存地址。例如,假设基址为10,000:
item index 0 1 2 3 memory address 10,000 10,001 10,002 10,003
字符串为了存储多维块,必须以某种方式使其几何形状适合线性存储器。在C和NumPy中,这是逐行完成的。2D示例为:
C
NumPy
| 0 1 2 3 --+------------------------ 0 | 0 1 2 3 1 | 4 5 6 7 2 | 8 9 10 11
型因此,例如,在这个3乘4的块中,2D索引(1, 2)将对应于线性索引6,即1 x 4 + 2。unravel_index做相反的事情。给定一个线性索引,它计算相应的ND索引。由于这取决于块尺寸,因此也必须通过这些尺寸。因此,在我们的例子中,我们可以从线性索引6中得到原始的2D索引(1, 2):
(1, 2)
6
1 x 4 + 2
unravel_index
ND
>>> np.unravel_index(6, (3, 4)) (1, 2)
型注:上述内容仅涉及一些细节。1)将项索引转换为存储器地址也必须考虑项大小。例如,整数通常具有4或8个字节。因此,在后一种情况下,项i的内存地址将是base + 8 x i。2). NumPy比建议的要灵活一些。如果需要,它可以按列组织ND数据。它甚至可以处理内存中不连续的数据,例如留下间隙等。额外阅读:ndarray内部存储器布局
i
base + 8 x i
ipakzgxi2#
我们将从文档中的一个示例开始。
>>> np.unravel_index([22, 41, 37], (7,6)) (array([3, 6, 6]), array([4, 5, 1]))
字符串首先,(7,6)指定我们要将索引转换回的目标数组的维度。第二,[22, 41, 37]是这个数组上的一些索引**如果数组是扁平的。**如果一个7乘6的数组是扁平的,它的索引将如下所示
(7,6)
[22, 41, 37]
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, *22*, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, *37*, 38, 39, 40, *41*]
型如果我们将这些索引恢复到它们在dim (7, 6)数组中的原始位置,则会是
(7, 6)
[[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17], [18, 19, 20, 21, *22*, 23], <- (3, 4) [24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35], [36, *37*, 38, 39, 40, *41*]] (6, 1) (6,5)
型unravel_index函数的返回值告诉你**如果数组不是扁平的,[22,41,37]**的索引应该是什么。如果数组不是扁平的,这些索引应该是[(3, 4), (6, 5), (6,1)]。换句话说,该函数将flatten数组中的索引传输回其未flatten版本。https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.unravel_index.html
[(3, 4), (6, 5), (6,1)]
yvfmudvl3#
这与其他两个答案在内容上没有什么不同,但它可能更直观。如果你有一个二维矩阵或数组,你可以用不同的方式引用它。您可以键入(row,col),以获取(row,col)处的值,或者您可以为每个单元格指定一个单个数字索引。unravel_index只是在矩阵中引用值的这两种方式之间进行转换。
的数据这可扩展到大于2的尺寸。您还应该知道np.ravel_multi_index(),它执行反向转换。注意它需要(row,col)和数组的形状。我还看到索引矩阵中有两个10。
gwo2fgha4#
我可以用一个很简单的例子来解释。这是用于np.ravel_multi_index以及np.unravel_index
>>> X = np.array([[4, 2], [9, 3], [8, 5], [3, 3], [5, 6]]) >>> X.shape (5, 2)
字符串找到所有值3在X中的位置:
>>> idx = np.where(X==3) >>> idx (array([1, 3, 3], dtype=int64), array([1, 0, 1], dtype=int64))
型即x = [1,3,3],y = [1,0,1]它返回索引的x,y(因为X是二维的)。如果对idx应用ravel_multi_index,则获得:
x = [1,3,3]
y = [1,0,1]
idx
>>> idx_flat = np.ravel_multi_index(idx, X.shape) >>> idx_flat array([3, 6, 7], dtype=int64)
型idx_flat是X的线性指数,其中值为3。从上面的例子中,我们可以理解:
idx_flat
结果索引将是X.ravel()的直接索引。您可以在下面的x_linear中进行验证:
X.ravel()
x_linear
>>> x_linear = X.ravel() >>> x_linear array([4, 2, 9, 3, 8, 5, 3, 3, 5, 6])
型然而,unravel_index非常简单,只是上面的反向(np.ravel_multi_index)
>>> idx = np.unravel_index(idx_flat , X.shape) >>> idx (array([1, 3, 3], dtype=int64), array([1, 0, 1], dtype=int64))
型与idx = np.where(X==3)相同
idx = np.where(X==3)
5t7ly7z55#
给定一个raveled_index到一个.ravel() ed数组中,np.unravel_index计算出到基数组中的等价的非展开索引:
raveled_index
.ravel()
import numpy as np my_array = np.random.random((100, 42)) raveled_array = my_array.ravel() raveled_index = 1337 unraveled_index = np.unravel_index(raveled_index, my_array.shape) assert raveled_array[raveled_index] == my_array[unraveled_index]
字符串两个很好的知道:
raveled_array
flat_array
flat_index
unraveled_index
multi_index
my_array.dim == N
np.ravel_multi_index
xfyts7mz6#
这仅适用于2D情况,但是在这种情况下返回的两个坐标np.unravel_index函数分别等效于进行楼层划分和应用模函数。
for j in range(1,1000): for i in range(j): assert(np.unravel_index(i,(987654321,j))==(i//j,i%j))
字符串形状数组的第一个元素(即987654321)是没有意义的,除了把一个上限多大的解开线性指数可以通过函数。
6条答案
按热度按时间ulydmbyx1#
计算机内存是线性寻址的。每个存储器单元对应于一个数字。一个内存块可以用一个基址和一个项索引来寻址,基址是它的第一个元素的内存地址。例如,假设基址为10,000:
字符串
为了存储多维块,必须以某种方式使其几何形状适合线性存储器。在
C
和NumPy
中,这是逐行完成的。2D示例为:型
因此,例如,在这个3乘4的块中,2D索引
(1, 2)
将对应于线性索引6
,即1 x 4 + 2
。unravel_index
做相反的事情。给定一个线性索引,它计算相应的ND
索引。由于这取决于块尺寸,因此也必须通过这些尺寸。因此,在我们的例子中,我们可以从线性索引6
中得到原始的2D索引(1, 2)
:型
注:上述内容仅涉及一些细节。1)将项索引转换为存储器地址也必须考虑项大小。例如,整数通常具有4或8个字节。因此,在后一种情况下,项
i
的内存地址将是base + 8 x i
。2). NumPy比建议的要灵活一些。如果需要,它可以按列组织ND
数据。它甚至可以处理内存中不连续的数据,例如留下间隙等。额外阅读:ndarray内部存储器布局
ipakzgxi2#
我们将从文档中的一个示例开始。
字符串
首先,
(7,6)
指定我们要将索引转换回的目标数组的维度。第二,[22, 41, 37]
是这个数组上的一些索引**如果数组是扁平的。**如果一个7乘6的数组是扁平的,它的索引将如下所示型
如果我们将这些索引恢复到它们在dim
(7, 6)
数组中的原始位置,则会是型
unravel_index
函数的返回值告诉你**如果数组不是扁平的,[22,41,37]**的索引应该是什么。如果数组不是扁平的,这些索引应该是[(3, 4), (6, 5), (6,1)]
。换句话说,该函数将flatten数组中的索引传输回其未flatten版本。https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.unravel_index.html
yvfmudvl3#
这与其他两个答案在内容上没有什么不同,但它可能更直观。如果你有一个二维矩阵或数组,你可以用不同的方式引用它。您可以键入(row,col),以获取(row,col)处的值,或者您可以为每个单元格指定一个单个数字索引。unravel_index只是在矩阵中引用值的这两种方式之间进行转换。
的数据
这可扩展到大于2的尺寸。您还应该知道np.ravel_multi_index(),它执行反向转换。注意它需要(row,col)和数组的形状。
我还看到索引矩阵中有两个10。
gwo2fgha4#
我可以用一个很简单的例子来解释。这是用于np.ravel_multi_index以及np.unravel_index
字符串
找到所有值3在X中的位置:
型
即
x = [1,3,3]
,y = [1,0,1]
它返回索引的x,y(因为X是二维的)。如果对
idx
应用ravel_multi_index,则获得:型
idx_flat
是X的线性指数,其中值为3。从上面的例子中,我们可以理解:
结果索引将是
X.ravel()
的直接索引。您可以在下面的x_linear
中进行验证:型
然而,unravel_index非常简单,只是上面的反向(np.ravel_multi_index)
型
与
idx = np.where(X==3)
相同5t7ly7z55#
给定一个
raveled_index
到一个.ravel()
ed数组中,np.unravel_index
计算出到基数组中的等价的非展开索引:字符串
两个很好的知道:
raveled_array
也称为flat_array
;因此,raveled_index
或flat_index
只不过是“扁平”数组的索引。此外,由于平面阵列“丢失”了其原始形状信息,因此在调用np.unravel_index
时需要添加此信息。unraveled_index
通常被称为multi_index
。这是因为您需要多个值(一个N元组)来索引任何具有my_array.dim == N
的数组中的元素。因此,np.unravel_index
的逆称为np.ravel_multi_index
。xfyts7mz6#
这仅适用于2D情况,但是在这种情况下返回的两个坐标np.unravel_index函数分别等效于进行楼层划分和应用模函数。
字符串
形状数组的第一个元素(即987654321)是没有意义的,除了把一个上限多大的解开线性指数可以通过函数。