PFE 3 and SciPy SciPy [ Scientific Algorithms ] linalg stats interpolate maxentrop cluster special y io fftpack odr

ndimage sparse integrate

signal optimize weave NumPy [ Data Structure Core ] fft random linalg

NDArray UFunc multi-dimensional fast array array object math operations Online Documentation

SCIPY DOCUMENTATION PAGE NUMPY EXAMPLES

http://www.scipy.org/Documentation http://www.scipy.org/Numpy_Example_List_With_Doc ndarray ndarray ndarray ndarray

Types

Types

Types

Types

ndarrays are similar to lists but all elements have to be of the same type http://docs.scipy.org/doc/numpy-1.10.1/user/basics.types.html Basic initializations

Basic initializations

Basic initializations

Basic initializations

Basic initializations

Type casting

Type casting

Type casting

Indexing, Slicing and Broadcasting

indexing Indexing, Slicing and Broadcasting

var[lower:upper:step]

indexing

slicing Indexing, Slicing and Broadcasting

indexing

slicing

broadcasting Multi-Dimensional Arrays DEFINITION >>> a = array([[ 0, 1, 2, 3], [10,11,12,13]]) >>> a array([[ 0, 1, 2, 3], [10,11,12,13]]) Multi-Dimensional Arrays DEFINITION >>> a = array([[ 0, 1, 2, 3], [10,11,12,13]]) >>> a array([[ 0, 1, 2, 3], [10,11,12,13]]) (ROWS, COLUMNS) >>> a.shape (2, 4) >>> shape(a) (2, 4)

Multi-Dimensional Arrays DEFINITION >>> a = array([[ 0, 1, 2, 3], [10,11,12,13]]) >>> a array([[ 0, 1, 2, 3], [10,11,12,13]]) (ROWS, COLUMNS) >>> a.shape (2, 4) >>> shape(a) (2, 4)

NUMBER OF ELEMENTS >>> a.size 8 >>> size(a) 8 Multi-Dimensional Arrays DEFINITION NUMBER OF DIMENSIONS >>> a = array([[ 0, 1, 2, 3], >>> a.ndims [10,11,12,13]]) 2 >>> a array([[ 0, 1, 2, 3], [10,11,12,13]]) (ROWS, COLUMNS) >>> a.shape (2, 4) >>> shape(a) (2, 4)

NUMBER OF ELEMENTS >>> a.size 8 >>> size(a) 8 Multi-Dimensional Arrays DEFINITION NUMBER OF DIMENSIONS >>> a = array([[ 0, 1, 2, 3], >>> a.ndims [10,11,12,13]]) 2 >>> a array([[ 0, 1, 2, 3], INDEXING ELEMENTS [10,11,12,13]]) >>> a[1,3] 13 column (ROWS, COLUMNS) row >>> a.shape >>> a[1,3] = -1 (2, 4) >>> a >>> shape(a) array([[ 0, 1, 2, 3], (2, 4) [10,11,12,-1]])

NUMBER OF ELEMENTS >>> a.size >>> a[1] 8 array([10, 11, 12, -1]) >>> size(a) 8 Reshape

2D Array Slicing

>>> a[0,3:5] 0 1 2 3 4 5 10 11 12 13 14 15 20 21 22 23 24 25 30 31 32 33 34 35 40 41 42 43 44 45 50 51 52 53 54 55 2D Array Slicing

>>> a[0,3:5] array([3, 4]) 0 1 2 3 4 5

10 11 12 13 14 15 20 21 22 23 24 25 30 31 32 33 34 35 40 41 42 43 44 45 50 51 52 53 54 55 2D Array Slicing

>>> a[0,3:5] array([3, 4]) 0 1 2 3 4 5

>>> a[4:,4:] 10 11 12 13 14 15

20 21 22 23 24 25 30 31 32 33 34 35 40 41 42 43 44 45 50 51 52 53 54 55 2D Array Slicing

>>> a[0,3:5] array([3, 4]) 0 1 2 3 4 5

>>> a[4:,4:] 10 11 12 13 14 15 array([[44, 45], [54, 55]]) 20 21 22 23 24 25

30 31 32 33 34 35 40 41 42 43 44 45 50 51 52 53 54 55 2D Array Slicing

>>> a[0,3:5] array([3, 4]) 0 1 2 3 4 5

>>> a[4:,4:] 10 11 12 13 14 15 array([[44, 45], [54, 55]]) 20 21 22 23 24 25

>>> a[:,2] 30 31 32 33 34 35 40 41 42 43 44 45 50 51 52 53 54 55 2D Array Slicing

>>> a[0,3:5] array([3, 4]) 0 1 2 3 4 5

>>> a[4:,4:] 10 11 12 13 14 15 array([[44, 45], [54, 55]]) 20 21 22 23 24 25

>>> a[:,2] array([2,12,22,32,42,52]) 30 31 32 33 34 35 40 41 42 43 44 45 50 51 52 53 54 55 2D Array Slicing

>>> a[0,3:5] array([3, 4]) 0 1 2 3 4 5

>>> a[4:,4:] 10 11 12 13 14 15 array([[44, 45], [54, 55]]) 20 21 22 23 24 25

>>> a[:,2] array([2,12,22,32,42,52]) 30 31 32 33 34 35 40 41 42 43 44 45 >>> a[2::2,::2] 50 51 52 53 54 55 2D Array Slicing

>>> a[0,3:5] array([3, 4]) 0 1 2 3 4 5

>>> a[4:,4:] 10 11 12 13 14 15 array([[44, 45], [54, 55]]) 20 21 22 23 24 25

>>> a[:,2] array([2,12,22,32,42,52]) 30 31 32 33 34 35 40 41 42 43 44 45 >>> a[2::2,::2] array([[20, 22, 24], 50 51 52 53 54 55 [40, 42, 44]]) Slices Are References Slices are references to memory in the original array. Changing values in a slice also changes the original array.

>>> a = array((0,1,2,3,4))

# create a slice containing only the # last element of a >>> b = a[2:4] >>> b array([2, 3]) >>> b[0] = 10

# changing b changed a! >>> a array([ 1, 2, 10, 3, 4]) Fancy Indexing

Positions

>>> a = arange(0,80,10)

# fancy indexing >>> y = a[[1, 2, -3]] >>> print y [10 20 50]

# function take >>> y = take(a,[1,2,-3]) >>> print y [10 20 50]

a 0 10 20 30 40 50 60 70

y 10 20 50 Fancy Indexing

Positions Boolean expressions

>>> a = arange(0,80,10) >>> mask = array([0,1,1,0,0,1,0,0], ... dtype=bool)

# fancy indexing # fancy indexing >>> y = a[[1, 2, -3]] >>> y = a[mask] >>> print y >>> print y [10 20 50] [10,20,50]

# function take # function compress >>> y = take(a,[1,2,-3]) >>> y = compress(mask, a) >>> print y >>> print y [10 20 50] [10,20,50]

a 0 10 20 30 40 50 60 70

y 10 20 50 Fancy Indexing in 2D

>>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45])

>>> a[3:,[0, 2, 5]] array([[30, 32, 35], [40, 42, 45]]) [50, 52, 55]])

>>> mask = array([1,0,1,0,0,1], dtype=bool) >>> a[mask,2] Unlike slicing, fancy indexing array([2,22,52]) creates copies instead of views into original arrays. Fancy Indexing in 2D

0 1 2 3 4 5 >>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45]) 10 11 12 13 14 15 20 21 22 23 24 25 >>> a[3:,[0, 2, 5]] array([[30, 32, 35], 30 31 32 33 34 35 [40, 42, 45]]) [50, 52, 55]]) 40 41 42 43 44 45

>>> mask = array([1,0,1,0,0,1], 50 51 52 53 54 55 dtype=bool) >>> a[mask,2] Unlike slicing, fancy indexing array([2,22,52]) creates copies instead of views into original arrays. Fancy Indexing in 2D

0 1 2 3 4 5 >>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45]) 10 11 12 13 14 15 20 21 22 23 24 25 >>> a[3:,[0, 2, 5]] array([[30, 32, 35], 30 31 32 33 34 35 [40, 42, 45]]) [50, 52, 55]]) 40 41 42 43 44 45

>>> mask = array([1,0,1,0,0,1], 50 51 52 53 54 55 dtype=bool) >>> a[mask,2] Unlike slicing, fancy indexing array([2,22,52]) creates copies instead of views into original arrays. Fancy Indexing in 2D

0 1 2 3 4 5 >>> a[(0,1,2,3,4),(1,2,3,4,5)] array([ 1, 12, 23, 34, 45]) 10 11 12 13 14 15 20 21 22 23 24 25 >>> a[3:,[0, 2, 5]] array([[30, 32, 35], 30 31 32 33 34 35 [40, 42, 45]]) [50, 52, 55]]) 40 41 42 43 44 45

>>> mask = array([1,0,1,0,0,1], 50 51 52 53 54 55 dtype=bool) >>> a[mask,2] Unlike slicing, fancy indexing array([2,22,52]) creates copies instead of views into original arrays. “Incomplete” Indexing a y

0 1 2 3 4 5 0 1 2 3 4 5 >>> y = a[:3] 10 11 12 13 14 15 10 11 12 13 14 15 20 21 22 23 24 25 20 21 22 23 24 25 30 31 32 33 34 35 40 41 42 43 44 45

condition a y >>> y = a[condition] 0 0 1 2 3 4 5 1 10 11 12 13 14 15 10 11 12 13 14 15 1 20 21 22 23 24 25 20 21 22 23 24 25 0 30 31 32 33 34 35 40 41 42 43 44 45 1 40 41 42 43 44 45 3D Example

2 1 0

# retrieve two slices from a # 3D cube via indexing >>> y = a[:,:,[2,-2]]

# the take() function also works a >>> y = take(a,[2,-2], axis=2)

y

NDArray Data Structure

The float32 data type describes the dtype * float32 array data elements dim count 2 12 bytes dimensions 3 3 4 bytes strides 12 4

data * 0 1 2 3 4 5 6 7 8 Memory block

0 1 2 Python View: 3 4 5 6 7 8 Indexing with None

None is a special index that inserts a new axis in the array at the specified location. Each None increases the array’s dimensionality by 1.

a 0 1 2

1 X 3 3 X 1 3 X 1 X 1 >>> y = a[None,:] >>> y = a[:,None] >>> y = a[:,None, None] >>> shape(y) >>> shape(y) >>> shape(y) (1, 3) (3, 1) (3, 1, 1)

0 2 1 1 0 1 2 0 2 Conditions

Conditions

Conditions

Conditions

Iterating over arrays • Over all elements – for element in A.flat: • In multi-dimensional arrays over rows – for row in A: • Over individual elements – for i in range(A.shape[0]): • for in range(A.shape[1]): Multi-dimensional broadcasting

>>> a = array((0,10,20,30)) >>> b = array((0,1,2)) >>> y = a[:, None] + b

0 0 1 2 0 1 2 10 + = 10 11 12 20 20 21 22 30 30 31 32 Universal Functions: ufunc • ufunc is a function that is applied to all elements of an array Mathematical functions

VECTORIZING FUNCTIONS

Vectorizing Functions SCALAR SINC FUNCTION SOLUTION >>> from numpy import vectorize def sinc(x): >>> vsinc = vectorize(sinc) if x == 0.0: >>> vsinc(x) return 1.0 array([-0.1981, -0.2122]) else:

w = pi*x >>> x2 = linspace(-5, 5, 101) return sin(w) / w >>> plot(x2, sinc(x2))

# attempt >>> x = array((1.3, 1.5)) >>> sinc(x) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() >>> x = r_[-5:5:100j] >>> y = vsinc(x) >>> plot(x, y) Stochastics

Exercises (no loops) • Create an array of 25 random floating-point numbers in the range [0, 100] and set the highest element equal to 200 and all numbers smaller than 50 equal to 0. • Create a 9x9 of random numbers (int32) in the range of -100 to 100. Using this matrix create an array that only contains the even elements sorted in ascending order. Exercise (no loops)

• Create a graph of the sine and cosine functions in the range from 0 do 3*PI. Evaluate where the function graphs are close to each other (distance < 0.1) and indicate this using points.

Exercise (no loops)

• Create a 500x2 matrix containing 500 2D points in the range [-1,1]2. Transform the points (x, y) to points (t, ) in the polar coordinate system. Visualize the points as a scatter plot, such that the points are colored with the color map jet if the angle is t < 180 - and with the color map terrain in the converse case.

Exercise

• Download the file populacje.txt which contains population numbers of rabbits, foxes and carrots for a given time period at an undisclosed location. Report the year in which each species had the greatest population number; for each year which species had the greatest population; the years where the total population of all species was greater than 100,000.