%pylab inline import numpy as np import sys # only need to get python version print("Python version: " + sys.version) print("Numpy version: " + np.__version__) # a vector: the argument to the array function is a Python list v = np.array([1,2,3,4]) v # a matrix: the argument to the array function is a nested Python list M = np.array([[1, 6], [3, 4]]) M type(v), type(M) v.shape M.shape M.size np.shape(M) np.size(M) M.dtype M = np.array([[1, 2], [3, 4]], dtype=np.float16) M # create a range x = np.arange(0, 10, 1) # arguments: start, stop, step x x = np.arange(-1, 1, 0.1) x # using linspace, both end points ARE included np.linspace(0, 10, 25) np.logspace(0, 10, 10, base=e) x, y = np.mgrid[0:5, 0:5] # similar to meshgrid in MATLAB x y from numpy import random # uniform random numbers in [0,1] random.rand(5,5) # standard normal distributed random numbers random.randn(5,5) np.zeros((3,3)) np.ones((3,3)) M.itemsize # bytes per element M.nbytes # number of bytes M.ndim # number of dimensions # v is a vector, and has only one dimension, taking one index v[0] # M is a matrix, or a 2 dimensional array, taking two indices M[1,1] M[1,:] # row 1 M[:,1] # column 1 M[0,0] = 1 M # also works for rows and columns M[1,:] = 0 M[:,1] = -1 M A = np.array([1,2,3,4,5]) A A[1:3] A[1:3] = [-2,-3] A A[::] # lower, upper, step all take the default values A[::2] # step is 2, lower and upper defaults to the beginning and end of the array A[:3] # first three elements A[3:] # elements from index 3 A = np.array([1,2,3,4,5]) A[-1] # the last element in the array A[-3:] # the last three elements A = np.array([[n+m*10 for n in range(5)] for m in range(5)]) A # a block from the original array A[1:4, 1:4] # strides A[::2, ::2] A[1] row_indices = [1, 2, 3] A[row_indices] col_indices = [1, 2, -1] # remember, index -1 means the last element A[row_indices, col_indices] B = array([n for n in range(5)]) B row_mask = array([True, False, True, False, False]) B[row_mask] # same thing row_mask = array([1,0,1,0,0], dtype=bool) B[row_mask] x = np.arange(0, 10, 0.5) x mask = (5 < x) * (x < 7.5) mask x[mask] indices = np.where(mask) indices x[indices] # this indexing is equivalent to the fancy indexing x[mask] np.diag(A) np.diag(A, -1) v2 = np.arange(-3,3) v2 row_indices = [1, 3, 5] v2[row_indices] # fancy indexing v2.take(row_indices) np.take([-3, -2, -1, 0, 1, 2], row_indices) which = [1, 0, 1, 0] choices = [[-2,-2,-2,-2], [5,5,5,5]] np.choose(which, choices) v1 = np.arange(0, 5) v1 * 2 v1 + 2 A * 2, A + 2 A * A # element-wise multiplication v1 * v1 A.shape, v1.shape A * v1 np.dot(A, A) np.dot(A, v1) np.dot(v1, v1) M = np.matrix(A) v = np.matrix(v1).T # make it a column vector v M * M M * v # inner product v.T * v # with matrix objects, standard matrix algebra applies v + M*v v = np.matrix([1,2,3,4,5,6]).T shape(M), shape(v) M * v C = np.matrix([[1j, 2j], [3j, 4j]]) C np.conjugate(C) C.H np.real(C) # same as: C.real np.imag(C) # same as: C.imag np.angle(C+1) # heads up MATLAB Users, angle is used instead of arg np.abs(C) inv(C) # equivalent to C.I C.I * C det(C) det(C.I) d = arange(0, 10) d # sum up all elements sum(d) # product of all elements prod(d+1) # cummulative sum cumsum(d) # cummulative product cumprod(d+1) # same as: diag(A).sum() trace(A) m = rand(3,3) m # global max m.max() # max in each column m.max(axis=0) # max in each row m.max(axis=1) A n, m = A.shape B = A.reshape((1,n*m)) B B[0,0:5] = 5 # modify the array B A # and the original variable is also changed. B is only a different view of the same data B = A.flatten() B B[0:5] = 10 B A # now A has not changed, because B's data is a copy of A's, not refering to the same data v = np.array([1,2,3]) np.shape(v) # make a column matrix of the vector v v[:, newaxis] # column matrix v[:,newaxis].shape # row matrix v[newaxis,:].shape a = np.array([[1, 2], [3, 4]]) # repeat each element 3 times np.repeat(a, 3) # tile the matrix 3 times np.tile(a, 3) b = np.array([[5, 6]]) np.concatenate((a, b), axis=0) np.concatenate((a, b.T), axis=1) np.vstack((a,b)) np.hstack((a,b.T)) A = np.array([[1, 2], [3, 4]]) A # now B is referring to the same array data as A B = A # changing B affects A B[0,0] = 10 B A B = copy(A) # now, if we modify B, A is not affected B[0,0] = -5 B A v = np.array([1,2,3,4]) for element in v: print(element) M = np.array([[1,2], [3,4]]) for row in M: print("row", row) for element in row: print(element) for row_idx, row in enumerate(M): print("row_idx", row_idx, "row", row) for col_idx, element in enumerate(row): print("col_idx", col_idx, "element", element) # update the matrix M: square each element M[row_idx, col_idx] = element ** 2 # each element in M is now squared M def Theta(x): """ Scalar implemenation of the Heaviside step function. """ if x >= 0: return 1 else: return 0 Theta(np.array([-3,-2,-1,0,1,2,3])) Theta_vec = np.vectorize(Theta) Theta_vec(np.array([-3,-2,-1,0,1,2,3])) def Theta(x): """ Vector-aware implemenation of the Heaviside step function. """ return 1 * (x >= 0) Theta(np.array([-3,-2,-1,0,1,2,3])) # still works for scalars as well Theta(-1.2), Theta(2.6) M if (M > 5).any(): print("at least one element in M is larger than 5") else: print("no element in M is larger than 5") if (M > 5).all(): print("all elements in M are larger than 5") else: print("all elements in M are not larger than 5") M.dtype M2 = M.astype(float) M2 M2.dtype M3 = M.astype(bool) M3