NumPy: Slicing and Indexing
By: Bhanu Soni
Tags: Numpy, Python, Machine Learning, Data Science, Programming

NumPy: Slicing and Indexing

One-dimensional slicing and indexing with NumPy, a Python package

NumPy is the fundamental package for scientific computing in Python.

One-dimensional slicing and indexing

Slicing of one-dimensional NumPy arrays works just like the slicing of Python lists. We can select a piece of an array from index 3 to 7 that extracts the elements 3 through 6:

In: a = arange(9)

In: a[3:7]

Out: array([3, 4, 5, 6])

We can select elements from index 0 to 7 with a step of 2:

In: a[:7:2] Out: array([0, 2, 4, 6])

Similarly as in Python, we can use negative indices and reverse the array:

In: a[::-1]

Out: array([8, 7, 6, 5, 4, 3, 2, 1, 0])

Time for action — slicing and indexing multidimensional arrays

A ndarray supports slicing over multiple dimensions. For convenience, we refer to many dimensions at once, with an ellipsis.

Create an array and reshape it: To illustrate, we will create an array with the arange function and reshape it:

In: b = arange(24).reshape(2,3,4)

In: b.shape Out: (2, 3, 4) In: b

Out:

array([[[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]],

[[12, 13, 14, 15],

[16, 17, 18, 19],

[20, 21, 22, 23]]])

The array b has 24 elements with values 0 to 23 and we reshaped it to be a 2-by-3-by-4, three-dimensional array.

We can visualize this as a two-story building with 12 rooms on each floor, 3 rows and 4 columns. As you have probably guessed, the reshape function changes the shape of an array. You give it a tuple of integers, corresponding to the new shape. If the dimensions are not compatible with the data, an exception is thrown.

2. Selecting a single cell: We can select a single room by using its three coordinates, namely, the floor, column, and row. For example, the room on the first floor, in the first row, and in the first column (you can have floor 0 and room 0 — it’s just a matter of convention) can be represented by:

In: b[0,0,0]

Out: 0

3. Selecting slices: If we don’t care about the floor, but still want the first column and row, we replace the first index by a : (colon) because we just need to specify the floor number and omit the other indices:

In: b[:,0,0]

Out: array([0, 12])

This selects the first floor In: b[0]

Out:

array([[ 0,1, 2, 3],

[ 4,5, 6, 7],

[ 8,9, 10, 11]])

We could also have written:

In: b[0,:, :]

Out:

array([[0,1, 2, 3],

[4,5, 6, 7],

[8,9, 10, 11]])

An ellipsis replaces multiple colons, so, the preceding code is equivalent to:

In: b[0,...]

Out:

array([[0,1, 2, 3],

[4,5, 6, 7],

[8,9, 10, 11]])

Further, we get the second row on the first floor with:

In: b[0,1]

Out: array([4, 5, 6, 7])

4. Using steps to slice: Furthermore, we can also select each second element of this selection:

In: b[0,1,::2]

Out: array([4, 6])

5. Using ellipsis to slice: If we want to select all the rooms on both floors that are in the second column, regardless of the row, we will type the following code snippet:

In: b[...,1]

Out:

array([[ 1, 5, 9],

[13, 17, 21]])

Similarly, we can select all the rooms on the second row, regardless of floor and column, by writing the following code snippet:

In: b[:,1]

Out:

array([[ 4, 5, 6, 7],

[16, 17, 18, 19]])

If we want to select rooms on the ground floor second column, then type the

following code snippet:

In: b[0,:,1]

Out: array([1, 5, 9])

6. Using negative indices: If we want to select the first floor, last column, then type the following code snippet:

In: b[0,:,-1]

Out: array([ 3,7, 11])

If we want to select rooms on the ground floor, last column reversed, then type the following code snippet:

In: b[0,::-1, -1]

Out: array([11, 7,3])

Every second element of that slice:

In: b[0,::2,-1]

Out: array([ 3, 11])

The command that reverses a one-dimensional array puts the top floor following the ground floor:

In: b[::-1]

Out:

array([[[12, 13, 14, 15],

[16, 17, 18, 19],

[20, 21, 22, 23]],

[[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]]])

What just happened?

We sliced a multidimensional NumPy array using several different methods.

Time for action — manipulating array shapes

We already learned about the reshape function. Another recurring task is flattening of arrays.

Ravel: Return a contiguous flattened array. A 1-D array, containing the elements of the input, is returned. A copy is made only if needed. As of NumPy 1.10, the returned array will have the same type as the input array. (for example, a masked array will be returned for a masked array input). We can accomplish this with the ravel function:

In: b

Out:

array([[[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]],

[[12, 13, 14, 15],

[16, 17, 18, 19],

[20, 21, 22, 23]]]) In: b.ravel()

Out:

array([ 0, 1, 2, 3, 4, 5, 6, 7, 15, 16,17, 18, 19, 20, 21, 22, 23])

2. Flatten: The appropriately-named function, flatten, does the same as ravel, but flatten always allocates new memory whereas ravel might return a view of

the array.Return a copy of the array collapsed into one dimension.

In: b.flatten()

Out:

array([ 0, 1, 2, 3, 4, 5, 6, 7,15, 16,17, 18, 19, 20, 21, 22, 23])

3. Setting the shape with a tuple: Besides the reshape function, we can also set the shape directly with a tuple, which is shown as follows:

In: b.shape = (6,4)

In: b

Out:array([[[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]],

[[12, 13, 14, 15],

[16, 17, 18, 19],

[20, 21, 22, 23]]])

As you can see, this changes the array directly. Now, we have a 6-by-4 array.

4. Transpose: Reverse or permute the axes of an array; returns the modified array. For an array, a with two axes, transpose(a) gives the matrix transpose. In linear algebra, it is common to transpose matrices. We can do that too, by using the following code:

In: b.transpose()

Out:

array([[ 0, 4, 8,12,16,20],

[ 1, 5, 9,13,17,21],

[ 2, 6, 10,14,18,22],

[ 3, 7, 11,15,19,23]]

5. Resize: Return a new array with the specified shape. If the new array is larger than the original array, then the new array is filled with repeated copies of a. Note that this behaviour is different from a.resize(new_shape) which fills with zeros instead of repeated copies of a. The resize method works just like the reshape method but modifies the array it operates on:

In: b.resize((2,12))

In: b

Out:

array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],

[12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])

What just happened?

We manipulated the shapes of NumPy arrays using the ravel function, function flatten , the reshape function, and the resize method.