Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an intuitive explanation of np.unravel_index?

Pretty much what the title says. I've read the documentation and I've played with the function for a while now but I can't discern what the physical manifestation of this transformation is.

like image 336
austinkjensen Avatar asked Jan 07 '18 09:01

austinkjensen


People also ask

What is NP Unravel_index?

unravel_index() function converts a flat index or array of flat indices into a tuple of coordinate arrays. Syntax : numpy.unravel_index(indices, shape, order = 'C') Parameters : indices : [array_like] An integer array whose elements are indices into the flattened version of an array of dimensions shape.


2 Answers

Computer memory is addressed linearly. Each memory cell corresponds to a number. A block of memory can be addressed in terms of a base, which is the memory address of its first element, and the item index. For example, assuming the base address is 10,000:

item index      0       1       2       3 memory address  10,000  10,001  10,002  10,003 

To store multi-dimensional blocks, their geometry must somehow be made to fit into linear memory. In C and NumPy, this is done row-by-row. A 2D example would be:

  | 0      1      2      3 --+------------------------ 0 | 0      1      2      3 1 | 4      5      6      7 2 | 8      9     10     11 

So, for example, in this 3-by-4 block the 2D index (1, 2) would correspond to the linear index 6 which is 1 x 4 + 2.

unravel_index does the inverse. Given a linear index, it computes the corresponding ND index. Since this depends on the block dimensions, these also have to be passed. So, in our example, we can get the original 2D index (1, 2) back from the linear index 6:

>>> np.unravel_index(6, (3, 4)) (1, 2) 

Note: The above glosses over a few details. 1) Translating the item index to memory address also has to account for item size. For example, an integer typically has 4 or 8 bytes. So, in the latter case, the memory address for item i would be base + 8 x i. 2). NumPy is a bit more flexible than suggested. It can organize ND data column-by-column if desired. It can even handle data that are not contiguous in memory but for example leave gaps, etc.


Bonus reading: internal memory layout of an ndarray

like image 69
Paul Panzer Avatar answered Sep 19 '22 15:09

Paul Panzer


We will start with an example in the documentation.

>>> np.unravel_index([22, 41, 37], (7,6)) (array([3, 6, 6]), array([4, 5, 1])) 

First, (7,6) specifies the dimension of target array that we want to turn the indices back into. Second, [22, 41, 37] are some indices on this array if the array is flattened. If a 7 by 6 array is flattened, its indices will look like

[ 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*] 

If we unflatten these indices back to their original positions in a dim (7, 6) array, it would be

      [[ 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) 

The return values of the unravel_index function tell you what should have been the indices of [22, 41, 37] if the array is not flattened. These indices should have been [(3, 4), (6, 5), (6,1)] if the array is not flattened. In other words, the function transfers the indices in a flatten array back to its unflatten version.

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

like image 22
Tai Avatar answered Sep 22 '22 15:09

Tai