import numpy as np
import time
First, a motivating example for why we might want a NUMerical PYthon (numpy) library.
Squaring a list of numbers:
num_elements = 1000000
input_array = list(range(num_elements))
start_time = time.time()
return_array = [0] * len(input_array)
for key, val in enumerate(input_array):
return_array[key] = val * val
print(time.time() - start_time)
0.1591188907623291
start_time = time.time()
return_array_vectorized = np.square(input_array)
print(time.time() - start_time)
0.044077396392822266
np.zeros(5)
array([0., 0., 0., 0., 0.])
np.identity(3)
array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
array_1 = np.array([[1,2],[3,4],[5,6]]) # An array with arbitrary elements.
array_1
array([[1, 2], [3, 4], [5, 6]])
array_1.shape
(3, 2)
type(array_1)
(numpy.ndarray, (3, 2))
array_1.shape
(3, 2)
array_1[1,1] # Access an element
4
array_1[1] # Access a row
array([3, 4])
array_1[:,1] # Access a column
array([2, 4, 6])
array_1[1,:] # Access a row
array([3, 4])
array_1[1]
array([3, 4])
array_1[[1,1,1]]
array([[3, 4], [3, 4], [3, 4]])
array_1[:,1]
array([2, 4, 6])
array_1[:,[1,1,1]]
array([[2, 2, 2], [4, 4, 4], [6, 6, 6]])
Perhaps one of the most useful is to convert a list of integers to 1-hot vectors:
np.eye(3)[[1,1,0,2]]
array([[0., 1., 0.], [0., 1., 0.], [1., 0., 0.], [0., 0., 1.]])
array_1 + [[1,1],[1,1],[1,1]]
array([[2, 3], [4, 5], [6, 7]])
array_1 * array_1 # elementwise multiplication
array([[ 1, 4], [ 9, 16], [25, 36]])
array_2 = np.add(array_1, 1) # array_1 + 1
array_2
array([[2, 3], [4, 5], [6, 7]])
array_2 = array_1 + 1
array_2
array([[2, 3], [4, 5], [6, 7]])
# Recall:
array_2.shape
(3, 2)
array_2 = array_1 + [1,2]
array_2
array([[2, 4], [4, 6], [6, 8]])
array_2 = array_1 + [1,2,3]
array_2
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-44-9210d012adc3> in <module>() ----> 1 array_2 = array_1 + [1,2,3] 2 array_2 ValueError: operands could not be broadcast together with shapes (3,2) (3,)
np.array([[1,2]]).shape
(1, 2)
array_2 = array_1 + [[1,2]]
array_2
array([[2, 4], [4, 6], [6, 8]])
array_1 * 2 # np.multiply(array_1, 2)
array([[ 2, 4], [ 6, 8], [10, 12]])
array_1 / 2.0 # np.multiply(array_1, 1/2.0) @
array([[0.5, 1. ], [1.5, 2. ], [2.5, 3. ]])
# Vector
array_3 = np.array([1,2,3])
array_4 = np.array([4,5,6])
np.dot(array_3, array_4)
32
# Or:
array_3.dot(array_4)
32
# Matrix
array_3 = np.array([[1, 2]]) # [1, 2]
array_4 = np.array([[3], [4]]) # [2, 1]
np.dot(array_3, array_4) # Inner-product
array([[11]])
array_5 = np.dot(array_4, array_3)
array_5
array([[3, 6], [4, 8]])
array_5.sum(axis=0) # np.mean(array_4, 0)
array([ 7, 14])
array_5.sum(axis=1) # np.mean(array_4, 0)
array([ 9, 12])
array_5.sum()
21
array_5.mean(axis=0)
array([3.5, 7. ])
array_5.std(axis=0)
array([0.5, 1. ])
array_5.max(axis=0)
array([4, 8])
array_5.shape
(2, 2)
M1 = array_1.T
M1
array([[1, 3, 5], [2, 4, 6]])
np.power(M1, 3) # M1 ^ 2?
array([[ 1, 27, 125], [ 8, 64, 216]])
e = np.square(M1) == np.power(M1, 2)
e
array([[ True, True, True], [ True, True, True]])
if e:
print('e is True')
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-99-4fab4d84926b> in <module>() ----> 1 if e: 2 print('e is True') ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
if np.all(e):
print('all entries of e are True')
all entries of e are True
if np.any(e):
print('at least 1 entry of e is')
at least 1 entry of e is
if np.any(e):
print('at least 1 entry of e is')
np.all(e, 0) # if it makes sense, you can pass an axis argument!
array([ True, True, True])
np.linalg.inv(np.array([[2, 0], [0, 2]]))
array([[0.5, 0. ], [0. , 0.5]])
np.linalg.inv(np.matmul(M1.T, M1)) # This should raise an exception.
--------------------------------------------------------------------------- LinAlgError Traceback (most recent call last) <ipython-input-106-9e5bbb853a28> in <module>() ----> 1 np.linalg.inv(np.matmul(M1.T, M1)) # This should raise an exception. ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in inv(a) 526 signature = 'D->D' if isComplexType(t) else 'd->d' 527 extobj = get_linalg_error_extobj(_raise_linalgerror_singular) --> 528 ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj) 529 return wrap(ainv.astype(result_t, copy=False)) 530 ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _raise_linalgerror_singular(err, flag) 87 88 def _raise_linalgerror_singular(err, flag): ---> 89 raise LinAlgError("Singular matrix") 90 91 def _raise_linalgerror_nonposdef(err, flag): LinAlgError: Singular matrix
A1 = np.array([[1, 1], [0, 1]])
x1 = np.array([[2], [2]])
b1 = np.matmul(A1, x1)
b1
array([[4], [2]])
x1_verify = np.linalg.solve(A1, b1)
all(x1 == x1_verify)
True
A2 = np.array([[1, 1], [2, 2]]) # Note that the rank of this matrix is 1.
x2 = np.array([[2], [3]])
potential_sol = np.matmul(A2, x2)
potential_sol
array([[ 5], [10]])
b2 = np.array([[5], [11]])
x2_verify = np.linalg.solve(A2, b2) # This should raise an exception.
# There is no selection of x to solve this linear system for A2 and b2.
--------------------------------------------------------------------------- LinAlgError Traceback (most recent call last) <ipython-input-111-56dd9bbf1477> in <module>() 1 b2 = np.array([[5], [11]]) ----> 2 x2_verify = np.linalg.solve(A2, b2) # This should raise an exception. 3 # There is no selection of x to solve this linear system for A2 and b2. ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in solve(a, b) 388 signature = 'DD->D' if isComplexType(t) else 'dd->d' 389 extobj = get_linalg_error_extobj(_raise_linalgerror_singular) --> 390 r = gufunc(a, b, signature=signature, extobj=extobj) 391 392 return wrap(r.astype(result_t, copy=False)) ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _raise_linalgerror_singular(err, flag) 87 88 def _raise_linalgerror_singular(err, flag): ---> 89 raise LinAlgError("Singular matrix") 90 91 def _raise_linalgerror_nonposdef(err, flag): LinAlgError: Singular matrix
x2_verify = np.linalg.solve(A2, potential_sol) # This should raise an exception.
# There happens to exist an x to solve this system, but numpy still fails.
--------------------------------------------------------------------------- LinAlgError Traceback (most recent call last) <ipython-input-112-ee72a78afdea> in <module>() ----> 1 x2_verify = np.linalg.solve(A2, potential_sol) # This should raise an exception. 2 # There happens to exist an x to solve this system, but numpy still fails. ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in solve(a, b) 388 signature = 'DD->D' if isComplexType(t) else 'dd->d' 389 extobj = get_linalg_error_extobj(_raise_linalgerror_singular) --> 390 r = gufunc(a, b, signature=signature, extobj=extobj) 391 392 return wrap(r.astype(result_t, copy=False)) ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _raise_linalgerror_singular(err, flag) 87 88 def _raise_linalgerror_singular(err, flag): ---> 89 raise LinAlgError("Singular matrix") 90 91 def _raise_linalgerror_nonposdef(err, flag): LinAlgError: Singular matrix
A3 = np.array([[1, 0, 0], [0, 1, 1]])
x3 = np.array([[1], [1], [1]])
b3 = np.matmul(A3, x3)
b3
array([[1], [2]])
np.linalg.solve(A3, b3) # This should raise an exception.
--------------------------------------------------------------------------- LinAlgError Traceback (most recent call last) <ipython-input-114-e0ec3f51dfe0> in <module>() ----> 1 np.linalg.solve(A3, b3) # This should raise an exception. ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in solve(a, b) 375 a, _ = _makearray(a) 376 _assertRankAtLeast2(a) --> 377 _assertNdSquareness(a) 378 b, wrap = _makearray(b) 379 t, result_t = _commonType(a, b) ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _assertNdSquareness(*arrays) 209 for a in arrays: 210 if max(a.shape[-2:]) != min(a.shape[-2:]): --> 211 raise LinAlgError('Last 2 dimensions of the array must be square') 212 213 def _assertFinite(*arrays): LinAlgError: Last 2 dimensions of the array must be square