什么是np.unravel_index的直观解释?

aus*_*sen 24 python indexing numpy

几乎就是标题所说的.我已经阅读了文档,并且我已经使用了该函数一段时间,但我无法分辨出这种转换的物理表现形式.

Tai*_*Tai 34

我们将从文档中的示例开始.

>>> np.unravel_index([22, 41, 37], (7,6))
(array([3, 6, 6]), array([4, 5, 1]))
Run Code Online (Sandbox Code Playgroud)

首先,(7,6)指定我们想要将索引转换回的目标数组的维度.其次,如果数组是扁平的,[22, 41, 37]则此数组上有一些索引.如果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, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
   34, 35, 36, *37*, 38, 39, 40, *41*]
Run Code Online (Sandbox Code Playgroud)

如果我们将这些指数放回到昏暗(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)
Run Code Online (Sandbox Code Playgroud)

如果数组没有展平,unravel_index函数的返回值告诉你应该是[22,41,37]的索引.[(3, 4), (6, 5), (6,1)]如果数组没有展平,则应该使用这些索引.换句话说,该函数将展平数组中的索引传回其未展平版本.

https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.unravel_index.html


Pau*_*zer 30

计算机存储器是线性处理的.每个存储器单元对应于一个数字.可以根据base(其第一个元素的内存地址)和项索引来寻址内存块.例如,假设基地址是10,000:

item index      0       1       2       3
memory address  10,000  10,001  10,002  10,003
Run Code Online (Sandbox Code Playgroud)

为了存储多维块,必须以某种方式使它们的几何形状适合线性存储器.在C和中NumPy,这是逐行完成的.2D示例将是:

  | 0      1      2      3
--+------------------------
0 | 0      1      2      3
1 | 4      5      6      7
2 | 8      9     10     11
Run Code Online (Sandbox Code Playgroud)

因此,例如,在该3×4块中的二维索引(1, 2)将对应于线性索引61 x 4 + 2.

unravel_index做反过来.给定线性索引,它计算相应的ND索引.由于这取决于块尺寸,因此也必须通过这些尺寸.因此,在我们的示例中,我们可以(1, 2)从线性索引中获取原始2D 索引6:

>>> np.unravel_index(6, (3, 4))
(1, 2)
Run Code Online (Sandbox Code Playgroud)

注意:上面的几个细节掩盖了上述内容.1)将项目索引转换为内存地址也必须考虑项目大小.例如,整数通常具有4或8个字节.因此,在后一种情况下,项目的内存地址i将是base + 8 x i.2).NumPy比建议的更灵活.ND如果需要,它可以逐列组织数据.它甚至可以处理内存中不连续的数据,例如留下间隙等.

  • @kmario23 https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html (2认同)

Jon*_*Jon 17

内容与其他两个答案没有什么不同,但它可能更直观.如果您有二维矩阵或数组,则可以通过不同方式引用它.您可以键入(row,col),以获取(row,col)的值,或者您可以为每个单元格指定单数字索引.unravel_index只是在这两种引用矩阵中的值的方式之间进行转换.

在此输入图像描述

这可以扩展到大于2的维度.您还应该知道np.ravel_index(),它执行反向转换.请注意,它需要索引和数组的形状.

我也看到我在索引矩阵中有两个10 - 哎呀.

  • 就直觉而言,这实际上正是我正在寻找的,谢谢。请问,这样做的动机是否仅仅是因为它使计算在计算上不那么复杂/更容易存储在内存中? (3认同)
  • 我想有很多原因/应用。我主要使用它的一种方法是:我有一个单宽度像素的骨架,我需要沿着它行走并返回我走过的地方的坐标。在“索引”空间而不是“行,列”空间中工作对我来说要简单得多,因为它将操作数量减少了一半。例如,如果您想查看是否已经走到 (2,1),则必须检查 2,然后检查 1。使用索引,我只检查“7”。基本示例,但它确实简化了事情。重申一下,还有许多其他应用程序:) (2认同)