# # Numpy introduction 1 (walkthrough) # # integers and floats (baseic data types): x = 3 print(type(x)) # Prints "" print(x) # Prints "3" print(x + 1) # Addition; prints "4" print(x - 1) # Subtraction; prints "2" print(x * 2) # Multiplication; prints "6" print(x ** 2) # Exponentiation; prints "9" x += 1 print(x) # Prints "4" x *= 2 print(x) # Prints "8" y = 2.5 print(type(y)) # Prints "" print(y, y + 1, y * 2, y ** 2) # Prints "2.5 3.5 5.0 6.25" # numpy import numpy as np a = np.array([1, 2, 3]) # Create a rank 1 array print(type(a)) # Prints "" print(a.shape) # Prints "(3,)" print(a[0], a[1], a[2]) # Prints "1 2 3" a[0] = 5 # Change an element of the array print(a) # Prints "[5, 2, 3]" b = np.array([[1,2,3],[4,5,6]]) # Create a rank 2 array print(b.shape) # Prints "(2, 3)" print(b[0, 0], b[0, 1], b[1, 0]) # Prints "1 2 4" # Creating arrays: a = np.zeros((2,2)) # Create an array of all zeros print(a) # Prints "[[ 0. 0.] # [ 0. 0.]]" b = np.ones((1,2)) # Create an array of all ones print(b) # Prints "[[ 1. 1.]]" c = np.full((2,2), 7) # Create a constant array print(c) # Prints "[[ 7. 7.] # [ 7. 7.]]" d = np.eye(2) # Create a 2x2 identity matrix print(d) # Prints "[[ 1. 0.] # [ 0. 1.]]" e = np.random.random((2,2)) # Create an array filled with random values print(e) # Might print("[[ 0.91940167 0.08143941] # [ 0.68744134 0.87236687]]" # Slicing: # Create the following rank 2 array with shape (3, 4) # [[ 1 2 3 4] # [ 5 6 7 8] # [ 9 10 11 12]] a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) # Use slicing to pull out the subarray consisting of the first 2 rows # and columns 1 and 2; b is the following array of shape (2, 2): # [[2 3] # [6 7]] b = a[:2, 1:3] # A slice of an array is a view into the same data, so modifying it # will modify the original array. print(a[0, 1]) # Prints "2" b[0, 0] = 77 # b[0, 0] is the same piece of data as a[0, 1] print(a[0, 1]) # Prints "77" # Mixing indexing and slicing: # Create the following rank 2 array with shape (3, 4) # [[ 1 2 3 4] # [ 5 6 7 8] # [ 9 10 11 12]] a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) # Two ways of accessing the data in the middle row of the array. # Mixing integer indexing with slices yields an array of lower rank, # while using only slices yields an array of the same rank as the # original array: row_r1 = a[1, :] # Rank 1 view of the second row of a row_r2 = a[1:2, :] # Rank 2 view of the second row of a print(row_r1, row_r1.shape) # Prints "[5 6 7 8] (4,)" print(row_r2, row_r2.shape) # Prints "[[5 6 7 8]] (1, 4)" # We can make the same distinction when accessing columns of an array: col_r1 = a[:, 1] col_r2 = a[:, 1:2] print(col_r1, col_r1.shape) # Prints "[ 2 6 10] (3,)" print(col_r2, col_r2.shape) # Prints "[[ 2] # [ 6] # [10]] (3, 1)" # Integer array indexing: a = np.array([[1,2], [3, 4], [5, 6]]) # An example of integer array indexing. # The returned array will have shape (3,) and print(a[[0, 1, 2], [0, 1, 0]]) # Prints "[1 4 5]" # The above example of integer array indexing is equivalent to this: print(np.array([a[0, 0], a[1, 1], a[2, 0]])) # Prints "[1 4 5]" # When using integer array indexing, you can reuse the same # element from the source array: print(a[[0, 0], [1, 1]]) # Prints "[2 2]" # Equivalent to the previous integer array indexing example print(np.array([a[0, 1], a[0, 1]])) # Prints "[2 2]" # Time comparison import time size_of_vec = 100000 def pure_python_version(): start = time.time() X = range(size_of_vec) Y = range(size_of_vec) Z = [] for i in range(len(X)): Z.append(X[i] + Y[i]) return time.time() - start def numpy_version(): start = time.time() X = np.arange(size_of_vec) Y = np.arange(size_of_vec) Z = X + Y return time.time() - start t1 = pure_python_version() t2 = numpy_version() print(t1, t2) print("Numpy is in this example " + str(t1/t2) + " faster!")