====== NumPy ======
Numerical Python
====== ndarray ======
Similar to pythons ''list'' object.
* All objects in an ''ndarray'' must have same datatype
* All math operators work on each individual element in an ''ndarray'
# Properties
a = np.ndarray((2,3,4))
a.shape # Tuple describing shape, e.g. (2,3,4)
a.ndim # Number of dimensions, equal to len(a.shape), e.g. 3
a.size # Total number of elements
a.dtype # Datatype of the elements
a.itemsize # Size in byte of an element
===== Creation =====
import numpy as np
#### np.array(content) ####
np.array(4)
# array(4)
np.array((1,2,3,4))
# array([1, 2, 3, 4])
np.array(((1,2,3),(4,5,6)))
# array([[1, 2, 3],
# [4, 5, 6]])
#### np.ndarray(shape) ####
np.ndarray(4)
# array([1.11949605e-311, 1.37961913e-306, 9.42677252e-321, 1.11829178e-311])
np.ndarray((2,4))
# array([[0. , 0.03 , 0.215, 0.4 ],
# [0.586, 0.77 , 0.954, 1. ]])
import numpy as np
a1 = np.zeros((4,3,2)) # Create 3-dimensional array with zeros
a2 = np.ones((3,4,5)) # Create 3-dimensional array with ones
a3 = np.arange(1,10) # Array with values 1..9
a4 = np.arange(10) # Array with values 0..9
a5 = np.arange(1,20,5) # Each 5th value between 1 to 19; [1, 6, 11, 16]
===== Indexing =====
a = np.arange(10) # a => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a1 = a[:6:2] # a1 => [0,2,4]
a[:6:2] = 30 # a => [30, 1, 30, 3, 30, 5, 6, 7, 8, 9]
# Note that a1 holds a reference to a, changes made to a1 is reflected in a
# 2d-array
B = A[row_start: row_stop : (row_step) , col_start : col_stop : (col_step)]
# Note that B holds a reference to A, changes made to B is reflected in A
# Using a list
a = np.arange(10) # a => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# a list naming the indices
l = [0, 2, 8, 9]
a[l]
a[[0,2,8,9]]
# or a list of bool, masking desired elements. Must be same dimension as the array.
bl = [False]*10
bl[3] = True
a[bl] # => [3]
# Note that this spawns a new ndarray, changes made to the resulting array is NOT reflected in the original array
# Using comparisons to create a masking list
a = np.arange(10) # a => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a[a>5] # => [6, 7, 8, 9]
# Note that this spawns a new ndarray, changes made to the resulting array is NOT reflected in the original array
====== Datatypes ======
[[https://numpy.org/doc/stable/reference/arrays.dtypes.html|Official documentation]]
^ Name ^ Datatype ^
| i | integer |
| b | byte |
| u | unsigned integer |
| f | float |
| M | datetime |
| m | timedelta |
| O | python object |
| S | zero terminated string |
| U | unicode string |
| c | complex float |
| V | raw data (void) |
====== Linear algebra and math ======
[[https://numpy.org/doc/stable/reference/routines.math.html|Math functions]]
np.dot(A,B) # Dot-product, sv skalärprodukt
np.linalg.det(A) # Determinant
np.transpose(A) # Transpose
np.identity(n) # N-th identity matrix
np.linalg.inv(A) # Inverse matrix
# Let v represent a polynomial
np.roots(v) # roots to the polynom
====== Universal functions, ufuncs ======
[[https://numpy.org/doc/stable/reference/ufuncs.html|Official documentation]]
Functions in the numpy library that operates on ndarrays in an element-wise manner.
import numpy as np
na = np.array([0.23, 2.3, 3.2, 4.1, 5.6])
np.cos(na) # Returns a new ndarray of same dimensions, with the result
np.log10(na)
# etc..
# Also arithmetic functions. Given nparray A and B of same size
elementwise_sum = A+B
elementwise_division = A/B
elementwise_square = A**B
elementwise_test = A != B
elementwise_test = A > B
====== resize, reshape, flatten, ravel ======
Of these four function, only resize creates a new array whilst the rest of them returns references or modify the original array.
A = np.ndarray((3,4)) # 3x4 array
B = A.flatten() # B is a new array
C = A.ravel() # C is a reference to A
A = np.arange(1,16,2)
A.resize(2,4) # Changes A to a 2x4 array
B = A.reshape(4,2) # B is a reference to A
====== Concatenation ======
np.vstack((A,B))
np.hstack((A,B))
np.concatenate((A,B), axis=1) # Similar to hstack
# All of these creates new arrays