https://numpy.org/
NumPy. The fundamental package for scientific computing with Python.
https://www.python-course.eu/numpy.php
Numpy Tutorial
https://numpy.org/doc/stable/numpy_2_0_migration_guide.html
NumPy 2.0 migration guide.
The precision of scalars is now preserved consistently.
The default integer used by NumPy is now 64bit on all 64bit systems.
Charles R. Harris et al, Array programming with NumPy, Nature 585, 357-362 (2020).
Pauli Virtanen et al, SciPy 1.0: fundamental algorithms for scientific computing in Python, Nature Methods 17, 261-272 (2020).
https://numpy.org/install/
If you already have Python, you can install NumPy with: ANACONDA # Best practice, use a virtual environment. conda install numpy PIP (in a virtual environment) pip install numpy APT (Debian Linux) Packages (with dependencies): python-numpy (Py2.7), python3-numpy (Py3).
NumPy stands for Numerical Python. NumPy is the fundamental package for scientific computing with Python. It contains among other things [version 1.16.2 in Debian 10, version 2.2.0 released 2024-12-0 (for Python 3.10-3.13)]:
NumPy’s main object is the homogeneous multidimensional array. It is a table of elements (usually numbers), all of the same type, indexed by a tuple of non-negative integers. In NumPy dimensions are called 'axes'.
import numpy as np # typical import under the 'np' alias print(np.__version__) # 1.16.2 for Debian 10 # also help(np) at the end a = np.arange(15).reshape(3, 5) # array object # arange() is like range() but returns an array. # np.arange( 10, 30, 5 ) # np.arange( 10, 30, 5, dtype=float ) # np.arange( 0, 2, 0.3 ) # it accepts float arguments print(a) # [[ 0 1 2 3 4] # [ 5 6 7 8 9] # [10 11 12 13 14]] # The shape of an array is the number of elements in each dimension. print(a.shape) # (3, 5), tuple, np.shape(a) print(a.ndim) # 2 print(a.dtype) # dtype('int64'), deduced from the sequence print(a.itemsize) # 8, size of bytes of each element of the array print(a.size) # 15, the number of items print(a.nbytes) # 120 assert a.nbytes == a.size * a.itemsize
lst = [24, 12, 57] arr = np.array([24, 12, 57])
# lst # | # o # +------+-----+-----+-----+ # | info | ref | ref | ref | list object # +------+--|--+--|--+--|--+ 64 + len(lst) * 8 bytes # | | | # o o o # +--+ +--+ +--+ # |24| |12| |57| len(lst) * 28 bytes # +--+ +--+ +--+ # int int int # Total: 64 + len(lst) * 8 + len(lst) * 28
# arr # | # o # +------+----+----+----+ # | info | 24 | 12 | 57 | array object # +------+----+----+----+ 96 + len(arr) * 8 bytes # int int int
# Tests in Python 3 and with a 64-bit laptop. import sys import numpy as np print(sys.getsizeof([])) # 64, empty list print(sys.getsizeof(np.array([]))) # 96, empty array lst = [24, 12, 57] print(sys.getsizeof(lst)) # 88 = 64 + 3 * 8, list object print(sys.getsizeof(lst[0])) # 28, int # This is a minimum estimation, as Python integers can use more than 28 bytes. arr = np.array([24, 12, 57]) print(arr.dtype) # dtype('int64') print(sys.getsizeof(arr)) # 120 = 96 + 3 * 8 arr = np.array([24, 12, 57], dtype="int8") # numbers from -127 to 127 print(sys.getsizeof(arr)) # 99 = 96 + 3 * 1 lst[0] = "alpha" print(sys.getsizeof("")) # 49 print(sys.getsizeof(lst)) # 88, the same print(sys.getsizeof(lst[0])) # 54 = 49 + 5, str print(sys.getsizeof(lst[1])) # 28, int
# Numpy arrays can be like Python lists. arr2 = np.array([1, 2.3, "word"], dtype=object) sys.getsizeof(arr2) # 120 = 96 + 3 * 8 (3 references) sys.getsizeof(arr2[0]) # 28, int sys.getsizeof(arr2[1]) # 24, float sys.getsizeof(arr2[2]) # 53 = 49 + 4, str # Total: 120 + 28 + 24 + 52 = 224 bytes
import timeit import numpy as np N = pow(10,6) x1 = list(range(N)) y1 = list(range(N)) x2 = np.arange(N) y2 = np.arange(N) print("Testing list comprehension ...") t1 = timeit.Timer(lambda: [x1[i] + y1[i] for i in range(N)]) print(t1.timeit(1)) # single run print("Testing zip ...") t1 = timeit.Timer(lambda: [a+b for (a,b) in zip(x1,y1)]) print(t1.timeit(1)) # single run print("Testing numpy ...") t1 = timeit.Timer(lambda: x2 + y2) print(t1.timeit(1)) # single run # Results: # Testing list comprehension ... # 0.0699481050032773 # Testing zip ... # 0.04706689599697711 # Testing numpy ... # 0.0011762819995055906
# Warning! x1 = list(range(0,120,20)) # [0, 20, 40, 60, 80, 100] y1 = [100] * 6 [a+b for (a,b) in zip(x1,y1)] # [100, 120, 140, 160, 180, 200] x2 = np.arange(0,120,20, dtype="int8") # array([0, 20, 40, 60, 80, 100], dtype=int8) y2 = np.array([100] * 6, dtype="int8") # array([100, 100, 100, 100, 100, 100], dtype=int8) x2 + y2 # array([ 100, 120, -116, -96, -76, -56], dtype=int8) ERROR out of range # Great power comes with great responsibility! (Peter Parker principle)