3

In Numpy, can we use a 2D array as index into a 1D array? What array array indexing rule applies to following code?

# 1D array
arr = np.arange(10)
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

# 2D index 
indx = np.array([[2, 4], [6, 8]])

# 2D index in 1D array
arr[indx]

# Output of above indexing is a 2D array!
array([[2, 4],[6, 8]])
5
  • Can you clarify exactly what you mean? The code you posted works correctly, and yes you can use a 2D array to index a 1D array. Commented Mar 12, 2018 at 7:53
  • I couldn't find the rule in numpy documentation, can you point me to relevant documentation where this type of indexing is discussed. I know this works, but i want to understand why. Commented Mar 12, 2018 at 7:57
  • From the docs: "Unlike lists and tuples, numpy arrays support multidimensional indexing for multidimensional arrays." but it's not so clear how it's done. Commented Mar 12, 2018 at 8:05
  • This is exactly what i want to understand. From experimenting one can see that, one can use N dimensional array to index a 1D array. The output will be an N dimensional array, provided the index are within the bounds of 1D array. Commented Mar 12, 2018 at 8:13
  • I'm pretty sure you can have as index an array of any size and shape as long as its elements are valid indexes of the original array (in this case integers 0..9) Commented Mar 12, 2018 at 8:22

1 Answer 1

1

What array array indexing rule applies to following code?

That's how numpy's advanced indexing works. The shape of result array is related to shape of index array, the array's shape and the axis you're passing the index. Here are some examples that passes a 3D array as index to the first axis of arrays with different shapes.

In [47]: a.shape
Out[47]: (2, 5)

In [48]: b = a[np.array([[[0],[1]],[[1],[1]]])]

In [49]: b.shape
Out[49]: (2, 2, 1, 5)

In [50]: arr.shape
Out[50]: (3, 3, 3)

In [51]: b = arr[np.array([[[0],[1]],[[1],[1]]])]

In [52]: b.shape
Out[52]: (2, 2, 1, 3, 3)

And here is what you get when you pass different arrays to different axises:

In [61]: b = arr[[[0],[2]],[[1],[0]]]

In [62]: b.shape
Out[62]: (2, 1, 3)

In [63]: arr.shape
Out[63]: (3, 3, 3)

In all of these indexings, Numpy will check multiple things, first off, it checks the type of the objects passed as index. Secondly, it compares the shapes of your index array with the shape of respective axis of your array. Thirdly, it checks if the result produces a valid Numpy array.

Here are some other examples:

In [64]: b = arr[[[[0],[2]]],[[1],[0]]]

In [65]: b.shape
Out[65]: (1, 2, 1, 3)

In [66]: b
Out[66]: 
array([[[[ 3,  4,  5]],

        [[18, 19, 20]]]])

In [67]: b = arr[[[[0],[2]]],[1],[0]]

In [68]: b
Out[68]: 
array([[[ 3],
        [21]]])

In [69]: b = arr[[[['a'],[2]]],[1],[0]]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-69-dba030ba9787> in <module>()
----> 1 b = arr[[[['a'],[2]]],[1],[0]]

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

In [70]: b = arr[[[[0],[2]]],[1],0]

In [71]: b = arr[[[[0],[2]]],[5],0]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-71-0962012e570a> in <module>()
----> 1 b = arr[[[[0],[2]]],[5],0]

IndexError: index 5 is out of bounds for axis 1 with size 3

In [72]: 

In [72]: b = arr[[[[0],[[2]]]],[5],0]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-72-9a520b0cb30e> in <module>()
----> 1 b = arr[[[[0],[[2]]]],[5],0]

ValueError: setting an array element with a sequence.

In [73]: b = arr[[[[0],[[2]]]],[5],[0]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-73-67187db6f452> in <module>()
----> 1 b = arr[[[[0],[[2]]]],[5],[0]]

ValueError: setting an array element with a sequence.
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, what I can conclude from above is that, as long as index array elements are within the bounds of the array to be indexed, we get a valid output. The shape of the output is the shape of the indexed array with the axis on which it was indexed, replaced by the shape of index array. For eg. index array shape , indx = (x1, x2, ...xn) , shape of array to be indexed, arr = (y1, y2....ym). Shape of output with indx array on axis 'k' of arr = (y1, y2... yk-1, x1, x2, .., xn, ..yk, yk+1.,,,ym).
@user8579809 Kind of but not completely. You cannot determine the result's shape simply like that because there are multiple cases and they'll generate results based on multiple rules (but similar though).
The best way to figure this out is to just play with different arrays and indexes in different shapes.
I used this to assign a 1D array with 2D array index... It's works too., but I don't know why...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.