Performant Python

Manipulating Arrays

Overview:

  • Teaching: 5 min
  • Exercises: 15 min

Questions

  • How do I manipulate the shape or size of an array?
  • What if I want to select by indexing?

Objectives

  • Understand that most general manipulations exists as numpy functions
  • Know that you can change the shape of an array
  • Understand the difference between reshape() and resize()
  • Know that you can select using index pairs, given as lists

Reshaping Arrays

First as always we must import numpy:

In [13]:
import numpy as np

Let's create ourselves an array as before and check its shape.

In [14]:
a = np.arange(6)
print("a", a, ", shape:", a.shape)
a [0 1 2 3 4 5] , shape: (6,)

We can change the shape of the array by modifying the shape directly, though this requires that the size of the array remains the same.

In [15]:
a.shape = (3,2)
print(a)
[[0 1]
 [2 3]
 [4 5]]

What happens if we call the reshape function?

a.reshape(2,3)

Solution

Reshape or Resize?

What is the difference between reshape and resize?

In [17]:
mat = np.arange(6)
print(mat)
mat1 = np.reshape(mat, (3, 2))
print(mat1)
[0 1 2 3 4 5]
[[0 1]
 [2 3]
 [4 5]]
In [18]:
mat1.base is mat
Out[18]:
True

Reshape creates a view of the object which has the shape specified in the function.

In [19]:
# Or can alter the size and shape of the array with
# resize(). May copy/pad depending on shape.
print(mat)
mat2 = np.resize(mat, (3, 2))
print(mat1)
[0 1 2 3 4 5]
[[0 1]
 [2 3]
 [4 5]]
In [20]:
mat2.base is mat # can also check this using id()
Out[20]:
False

Ressize creates a copy of the object which has the shape specified in the function.

Manipulation Functions

Using help, tab auto-completion or otherwise, experiment with some of the functions available with numpy that sound like they manipulate arrays.

Fancy indexing

Fancy indexing allows us to select elements from an existing array using pairs of lists which specify the 'rows' and 'columns' that we want to select. In this case numpy creates a copy.

In [21]:
p = np.array([[0, 1, 2],[3, 4, 5],
              [6, 7, 8],[9, 10, 11]]) 
print(p)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]

Let's now create two sets of indices and make our new selection

In [22]:
rows = [0,0,3,3]   # indices for rows
cols = [0,2,0,2]   # indices for columns
q=p[rows,cols]
print(q)
[ 0  2  9 11]

Finally we can modify one of the arrays, print them and verify that the new array is not a view on the original array.

In [23]:
# ... check if a is a view or a copy
q[0]=1000
print(q)
print(p)
[1000    2    9   11]
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
In [24]:
q.base is p
Out[24]:
False

Key Points:

  • Most general manipulations exists as numpy functions
  • Changing the size attribute directly, changes the shape of an array
  • reshape() creates a new view on an array
  • resize() creates a copy of an array
  • When you can select elements using index pairs, given as lists, numpy creates a copy