Basics of Numerical Python Arrays (numpy)

1. In-place Arithmetics


In [2]:
import numpy as np

Case 1: a = a+b

The sum is first computed and resulting in a new array and the a is bound to the new array


In [ ]:
a = np.array(range(10000000))
b = np.array(range(9999999,-1,-1))

In [ ]:
%%time
a = a + b

Case 2: a += b

The elements of b are directly added into the elements of a (in memory) - no intermediate array. These operators implement the so-called "in-place arithmetics" (e.g., +=, *=, /=, -= )


In [ ]:
a = np.array(range(10000000))
b = np.array(range(9999999,-1,-1))

In [ ]:
%%time
a +=b

2. Vectorization


In [ ]:
#Apply function to a complete array instead of writing loop to iterate over all elements of the array. 
#This is called vectorization. The opposite of vectorization (for loops) is known as the scalar implementation

def f(x):
    return x*np.exp(4)

print(f(a))

3. Slicing and reshape

Array slicing

x[i:j:s] 

picks out the elements starting with index i and stepping s indices at the time up to, but not including, j.


In [ ]:
x = np.array(range(100))

x[1:-1] # picks out all elements except the first and the last, but contrary to lists, a[1:-1] is not a copy of the data in a.
x[0:-1:2] # picks out every two elements up to, but not including, the last element, while 
x[::4] # picks out every four elements in the whole array.

Array shape manipulation


In [ ]:
a = np.linspace(-1, 1, 6)
print (a)

a.shape
a.size

# rows, columns
a.shape = (2, 3) 
a = a.reshape(2, 3) # alternative

a.shape
print (a)

# len(a) always returns the length of the first dimension of an array. -> no. of rows

Exercise

1. Create a 10x10 2d array with 1 on the border and 0 inside


In [ ]:
Z = np.ones((10,10))
Z[1:-1,1:-1] = 0
print(Z)

2. Create a structured array representing a position (x,y) and a color (r,g,b)


In [3]:
Z = np.zeros(10, [ ('position', [ ('x', float, 1),
                                   ('y', float, 1)]),
                    ('color',    [ ('r', float, 1),
                                   ('g', float, 1),
                                   ('b', float, 1)])])
print(Z)


[(( 0.,  0.), ( 0.,  0.,  0.)) (( 0.,  0.), ( 0.,  0.,  0.))
 (( 0.,  0.), ( 0.,  0.,  0.)) (( 0.,  0.), ( 0.,  0.,  0.))
 (( 0.,  0.), ( 0.,  0.,  0.)) (( 0.,  0.), ( 0.,  0.,  0.))
 (( 0.,  0.), ( 0.,  0.,  0.)) (( 0.,  0.), ( 0.,  0.,  0.))
 (( 0.,  0.), ( 0.,  0.,  0.)) (( 0.,  0.), ( 0.,  0.,  0.))]

3. Consider a large vector Z, compute Z to the power of 3 using 2 different methods


In [ ]:
x = np.random.rand(5e7)

%timeit np.power(x,3)
%timeit x*x*x