Numpy tutorial

blockquote not implemented

Reference

Call the function

np.func(a, x, y) is the same as a.func(x, y).

Convention

The common short name for numpy is np.

import numpy as np
np.__version__
0.8s
Python

Creating an array from a sequence

array(seq), asarray(seq)

seq can be a tuple, list, or a numpy array.

asarray() does not make a new copy if seq is already a numpy array.

Creating a 1D numpy array from a list.

Array basics

  • a.ndim : number of dimensions

  • a.shape: Tuple of lengths for each dimension

  • a.size : total size (product of shape) = len(a)

  • a.dtype: data type

  • a[i] : accessing i th element in the 1D array (start from 0)

  • a[i, j]: accessing element i th row, j th column (2D array, start from 0)

  • a[:, j]: accessing j th column(2D array)

  • a[i, :]: accessing j th row (2D array)

  • a.T : Transpose of a

  • a.copy(): make a copy of a that does not share memory

  • a.reshape(shape): reshape the array if the new size is compatible (i.e. the same total size)

a = np.array([1, 9, 8, 7])
a
0.0s
Python
a.ndim
0.0s
Python
a.shape
0.0s
Python
a.size
0.0s
Python
a.dtype
0.0s
Python
a[3]
0.0s
Python

For complex numbers, j being the imaginary part.

np.array([1+2j, 3+4j, 5+6*1j]).dtype
0.0s
Python

Creating a multidimensional array from a nested list , with complex numbers

b = np.asarray([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0+1j]])
b
0.0s
Python
b.ndim
0.0s
Python
b.shape
0.0s
Python
b.dtype
0.0s
Python
b[1, :]
0.0s
Python
b[:, 0]
0.0s
Python
b.T
0.0s
Python
b.reshape((3, 2))
0.0s
Python
b.reshape((1, -1)) # -1 mean caculate dim automatically
0.0s
Python

Creating an array from a function

  • arange(start, stop, step)

  • linspace(start, stop, num, endpoint=True)

  • logspace(start, stop, num, endpoint=True)

  • ones((d1, d2, ...))

  • ones_like(arr)

  • zeros((d1, d2, ...))

  • zeros_like(arr)

  • full((d1, d2, ...), val)

  • eye(k)

  • diag(seq)

  • fromfunction(f, (d1, d2, ...))

  • fromiter(iter)

  • meshgrid(x1, x2, ...)

np.arange(10, 0, -1)
0.0s
Python
np.linspace(0, 1, 5)
0.0s
Python
np.linspace(0, 1, 5, endpoint=False)
0.0s
Python
np.logspace(-10.0, 10.0, 11)
0.0s
Python
np.ones((3, 3))
0.0s
Python
a = np.arange(5.0)
print(np.ones_like(a))
0.3s
Python
[1. 1. 1. 1. 1.]
np.full((3, 4), 42)
0.0s
Python
np.full_like(a, 69)
0.0s
Python
np.eye(3)
0.0s
Python
np.diag([4, 5, 6, 7])
0.0s
Python
np.fromfunction(lambda i, j: i >= j, (4, 4))
0.0s
Python
np.fromiter((x*x for x in range(5)) , dtype=np.float)
0.0s
Python
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
# sparse=True to save some memory
xx, yy = np.meshgrid(x, y, sparse=True)
print('xx =', xx, sep='\n')
print('yy =', yy, sep='\n')
plt.contourf(x,y, np.sin(xx**2 + yy**2) / (xx**2 + yy**2))
plt.colorbar()
2.6s
Python
xx = [[-5. -4.8989899 -4.7979798 -4.6969697 -4.5959596 -4.49494949 -4.39393939 -4.29292929 -4.19191919 -4.09090909 -3.98989899 -3.88888889 -3.78787879 -3.68686869 -3.58585859 -3.48484848 -3.38383838 -3.28282828 -3.18181818 -3.08080808 -2.97979798 -2.87878788 -2.77777778 -2.67676768 -2.57575758 -2.47474747 -2.37373737 -2.27272727 -2.17171717 -2.07070707 -1.96969697 -1.86868687 -1.76767677 -1.66666667 -1.56565657 -1.46464646 -1.36363636 -1.26262626 -1.16161616 -1.06060606 -0.95959596 -0.85858586 -0.75757576 -0.65656566 -0.55555556 -0.45454545 -0.35353535 -0.25252525 -0.15151515 -0.05050505 0.05050505 0.15151515 0.25252525 0.35353535 0.45454545 0.55555556 0.65656566 0.75757576 0.85858586 0.95959596 1.06060606 1.16161616 1.26262626 1.36363636 1.46464646 1.56565657 1.66666667 1.76767677 1.86868687 1.96969697 2.07070707 2.17171717 2.27272727 2.37373737 2.47474747 2.57575758 2.67676768 2.77777778 2.87878788 2.97979798 3.08080808 3.18181818 3.28282828 3.38383838 3.48484848 3.58585859 3.68686869 3.78787879 3.88888889 3.98989899 4.09090909 4.19191919 4.29292929 4.39393939 4.49494949 4.5959596 4.6969697 4.7979798 4.8989899 5. ]] yy = [[-5. ] [-4.8989899 ] [-4.7979798 ] [-4.6969697 ] [-4.5959596 ] [-4.49494949] [-4.39393939] [-4.29292929] [-4.19191919] [-4.09090909] [-3.98989899] [-3.88888889] [-3.78787879] [-3.68686869] [-3.58585859] [-3.48484848] [-3.38383838] [-3.28282828] [-3.18181818] [-3.08080808] [-2.97979798] [-2.87878788] [-2.77777778] [-2.67676768] [-2.57575758] [-2.47474747] [-2.37373737] [-2.27272727] [-2.17171717] [-2.07070707] [-1.96969697] [-1.86868687] [-1.76767677] [-1.66666667] [-1.56565657] [-1.46464646] [-1.36363636] [-1.26262626] [-1.16161616] [-1.06060606] [-0.95959596] [-0.85858586] [-0.75757576] [-0.65656566] [-0.55555556] [-0.45454545] [-0.35353535] [-0.25252525] [-0.15151515] [-0.05050505] [ 0.05050505] [ 0.15151515] [ 0.25252525] [ 0.35353535] [ 0.45454545] [ 0.55555556] [ 0.65656566] [ 0.75757576] [ 0.85858586] [ 0.95959596] [ 1.06060606] [ 1.16161616] [ 1.26262626] [ 1.36363636] [ 1.46464646] [ 1.56565657] [ 1.66666667] [ 1.76767677] [ 1.86868687] [ 1.96969697] [ 2.07070707] [ 2.17171717] [ 2.27272727] [ 2.37373737] [ 2.47474747] [ 2.57575758] [ 2.67676768] [ 2.77777778] [ 2.87878788] [ 2.97979798] [ 3.08080808] [ 3.18181818] [ 3.28282828] [ 3.38383838] [ 3.48484848] [ 3.58585859] [ 3.68686869] [ 3.78787879] [ 3.88888889] [ 3.98989899] [ 4.09090909] [ 4.19191919] [ 4.29292929] [ 4.39393939] [ 4.49494949] [ 4.5959596 ] [ 4.6969697 ] [ 4.7979798 ] [ 4.8989899 ] [ 5. ]]

Random

The new API: https://numpy.org/doc/stable/reference/random/index.html?highlight=random#module-numpy.random

from numpy.random import default_rng
rng = default_rng()
0.0s
Python
rng.random()
0.0s
Python
# Uniform [0, 1)
rng.random((4, 3))
0.0s
Python
# Integers
rng.integers(1, 7, (10, 20))
0.0s
Python
# Standard uniform distribution
rng.standard_normal(10)
0.0s
Python
# Random choice
choices = np.array(["one", "two"])
# Select by index
choices[rng.integers(0, 2, (3, 4))]
0.0s
Python
# Or choice function, prob weights supported
rng.choice(choices, size=(5, 3), p=[0.3, 0.7])
0.0s
Python

Selecting elements

a = np.arange(10)
a
0.0s
Python
# a[idx]
a[0], a[3], a[7]
0.0s
Python
# a[[indices]]
a[[0, 3, 7]]
0.0s
Python
# a[condition]
# Selection from an array of true/false value
a[a<5]
0.0s
Python
# Slice: a[start:end:step]
a[1::2]
0.0s
Python
# Reverse
a[::-1]
0.0s
Python
# Mutating the elements
a[0] = 1000
a
0.0s
Python

Indexing for 2D / 3D arrays

In 2D, the first dimension corresponds to rows, the second to columns. Numpy is row-major by default, as in C-styled arrays.

a[i, j] for the element from ith row and jth column.

b = np.arange(25).reshape((5,5))
b
0.0s
Python
# Each index is separated by comma
b[2, 3]
0.0s
Python
# Slices share the same underlying object of the original.
c = b[1::2, 1::2]
c
0.0s
Python
c[0, 0] = 666  # Mutates b !!!
print("After mutating:")
b
0.3s
Python
After mutating:
np.may_share_memory(c, b)
0.0s
Python
# Use copy to prevent unwanted overwriting
a = np.arange(10)
c = a[::2].copy()
c[0] = 12
a
0.1s
Python
# combining assignment and slicing
a = np.arange(10)
a[5:] = 10
a
0.0s
Python
b = np.arange(5)
a[5:] = b[::-1]
a
0.0s
Python

Numerical operations on arrays

  • Element-wise (broadcasting) operations by default.

  • Some math functions could be found in numpy (e.g. sin, cos): use np.lookfor(desc.)

  • Others could be found in scipy documentations.

a = np.arange(10)
a
0.0s
Python
a+1
0.0s
Python
a-3
0.0s
Python
a*2
0.0s
Python
a/4
0.0s
Python
2**a
0.0s
Python

With an array: Only if dimension sizes are compatible: either the same or 1.

a = np.array([[1, 2, 3, 4], 
              [5, 6, 7, 8]])
b = rng.random((2, 4))
0.0s
Python
a+b
0.0s
Python
a-b
0.0s
Python
a*b
0.0s
Python
a/b
0.0s
Python
np.sin(b)
0.0s
Python
a = np.array([1, 2, 3, 4])
b = np.array([4, 2, 2, 4])
a == b
0.0s
Python
a = np.arange(1, 10)
b = np.arange(1, 8).reshape((-1, 1))
0.0s
Python
a
0.0s
Python
b
0.0s
Python
# Broadcasting: A(1*M) * B(N*1) = C(N * M)
a*b
0.0s
Python

Matrix multiplication

dot(a, b), a@b

a = rng.random((5, 5))
b = rng.random((5, 5))
0.0s
Python
# Element-wise multiplication
a*b
0.0s
Python
# Matrix multiplication
a@b
0.0s
Python
# Matrix multiplication
np.dot(a,b)
0.0s
Python
# No need to transpose 1D array for `dot(a, b)`
a = rng.random((5, 5))
b = rng.random(5)
c = rng.random(5)
0.0s
Python
# Matrix x vector
np.dot(a,b)
0.0s
Python
# Vector * vector
np.dot(c,b)
0.0s
Python

Combing Arrays

This one will give your headaches.

  • concatenate((a, b), axis=n)

  • stack((a,b), axis=n)

The former joins arrays in the existing axis; the latter creates a new axis.

a = np.arange(0, 10)
b = np.arange(0, 10) + 10
# along the row (1st axis), existing axis
np.concatenate((a, b), axis=0)
0.0s
Python
# along the column (2nd axis)
np.stack((a, b), axis=1)
0.0s
Python

Reduction

sum(v, axis=n), cumsum(v, axis=n)

a = np.arange(0, 6).reshape((2, 3))
a
0.0s
Python
np.sum(a)
0.0s
Python
np.sum(a, axis=1)
0.0s
Python
np.sum(a, axis=0)
0.0s
Python
np.cumsum(a)
0.0s
Python
np.cumsum(a, axis=1)
0.0s
Python
np.cumsum(a, axis=0)
0.0s
Python
  • amin(v, axis=n)

  • amax(v, axis=n)

  • minimum(a, b)

  • maximum(a, b)

  • argmin(v, axis=n)

  • argmax(v, axis=n)

np.amin(a)
0.0s
Python
np.argmin(a)
0.0s
Python
np.amax(a)
0.0s
Python
np.argmax(a)
0.0s
Python
b = (rng.standard_normal((2, 3)) + 1) * 5
b
0.0s
Python
np.minimum(a, b)
0.0s
Python
np.maximum(a, b)
0.0s
Python
np.all([True, True, False])
0.0s
Python
np.any([True, True, False])
0.0s
Python
Runtimes (1)