A place for study and research

Numpy Quick Start

|

Introduction

NumPy是Python語言的一個擴充程式庫。 支援高階大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式函式庫。

The Basics

Important attributes of an ndarray

import numpy as np 

a = np.arange(15).reshape(3,5) # a is 3*5 ndarray

a.shape # return (3,5)  

a.ndim # return 2 for a's dimension

a.dtype # return dtype('int64')

a.dtype.name # return 'int64' the datatype of elements in a

a.size # return 15 the number of elements in a

type(a) # return <type 'numpy.ndarray'>

b = np.array([6, 7, 8]) # create 1*3 ndarray

Array creation

import numpy as np

a = np.array(1, 2, 3, 4) # wrong
a = np.array([1, 2, 3, 4]) # right

a1 = np.arange(6) # 1d array
a2 = np.arange(12).reshape(4,3) # 2d array
a3 = np.arange(24).reshape(2,3,4) # 3d array

b = np.array([1, 2, 3], dtype=complex) # assign dtype=complex

np.zeros((3,4)) # 3*4 array filled with 0

np.ones((2,3,4), dtype=np.int16) # 2*3*4 array filled with 1 

np.empty((2,3)) # 2*3 array filled with  uninitiallized value

np.arange(10, 30, 5) # np.arange(start, end, step) 
np.arange(0, 2, 0.3) # step accepts float number

Example

import numpy as np
import matplotlib.pyplot as plt

np.linspace(0, 2, 9) # 9 numbers from 0 to 2
x = np.linspace(0, 2*np.pi, 100)
f = np.sin(x)

plt.plot(x,f)
plt.show()

Basic operations

import numpy as np

a = np.array([20,30,40,50])

b = np.arange(4) # array([0, 1, 2, 3])

c = a-b # array([20, 29, 38, 47])

b**2 # array([0, 1, 4, 9])

10*np.sin(a) 

a<35 # array([ True, True, False, False])
A = np.array([[1,1],[0,1]])

b = np.array([[2,0],[3,4]])

A * B # elementwise product

A @ B # matrix product

A.dot(B) # another matrix product
a = np.ones((2,3), dtype=int)

b = np.random.random((2,3))

c = np.exp(b+1j) # dtype of c is complex128

a *= 3

b += a

a += b #error, b is not automatically converted to integer type
a = np.arange(6) # array([0, 1, 2, 3, 4, 5])

a.sum() # return 15

a.min() # return 0

a.max() # return 5

b = np.arange(12).reshape(3,4)

b.sum(axis=0) # sum of each column

b.min(axis=1) # min of each row

b.cumsum(axis=1) # cumulative sum along each row

Create array from function

import numpy as np
def f(x,y):
	return 10*x+y
b = np.fromfunction(f,(5,4),dtype=int)
>>> b
array([[ 0, 1, 2, 3],
	   [10, 11, 12, 13],
	   [20, 21, 22, 23],
	   [30, 31, 32, 33],
	   [40, 41, 42, 43]])

>>> b[2,3]
23
>>> b[0:5, 1] # each row in the second column of b
array([ 1, 11, 21, 31, 41])
>>> b[ : ,1] # equivalent to the previous example
array([ 1, 11, 21, 31, 41])
>>> b[1:3, : ] # each column in the second and third row of b
array([[10, 11, 12, 13],
	   [20, 21, 22, 23]])

Shape manipulation

import numpy as np

a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 2., 8., 0., 6.],
	   [ 4., 5., 1., 1.],
	   [ 8., 9., 3., 6.]])
>>> a.shape
(3, 4)
>>> a.ravel() # returns the array, flattened
array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.])
>>> a.reshape(6,2) # returns the array with a modified shape
array([[ 2., 8.],
	   [ 0., 6.],
	   [ 4., 5.],
	   [ 1., 1.],
	   [ 8., 9.],
	   [ 3., 6.]])
>>> a.T # returns the array, transposed
array([[ 2., 4., 8.],
	   [ 8., 5., 9.],
	   [ 0., 1., 3.],
	   [ 6., 1., 6.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)

Stacking together different arrays

>>> a = np.floor(10*np.random.random((2,2)))
>>> a
array([[ 8., 8.],
	   [ 0., 0.]])

>>> b = np.floor(10*np.random.random((2,2)))
>>> b
array([[ 1., 8.],
	   [ 0., 4.]])

>>> np.vstack((a,b))
array([[ 8., 8.],
	   [ 0., 0.],
	   [ 1., 8.],
	   [ 0., 4.]])

>>> np.hstack((a,b))
array([[ 8., 8., 1., 8.],
	   [ 0., 0., 0., 4.]])

>>> np.column_stack((a,b)) # with 2D arrays
array([[ 8., 8., 1., 8.],
	   [ 0., 0., 0., 4.]])
>>> a = np.array([4.,2.])
>>> b = np.array([3.,8.])
>>> np.column_stack((a,b)) # returns a 2D array
array([[ 4., 3.],
	   [ 2., 8.]])

>>> np.hstack((a,b)) # the result is different
array([ 4., 2., 3., 8.])

>>> a[:,np.newaxis] # this allows to have a 2D columns vector
array([[ 4.],
	   [ 2.]])

>>> np.column_stack((a[:,np.newaxis],b[:,np.newaxis]))
array([[ 4., 3.],
	   [ 2., 8.]])
>>> np.hstack((a[:,np.newaxis],b[:,np.newaxis])) # the result is the same
array([[ 4., 3.],
	   [ 2., 8.]])

Splitting one array into several smaller ones

>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.],
	  [ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]])

>>> np.hsplit(a,3) # Split a into 3
[array([[ 9., 5., 6., 3.],
		[ 1., 4., 9., 2.]]),
 array([[ 6., 8., 0., 7.],
		[ 2., 1., 0., 6.]]),
 array([[ 9., 7., 2., 7.],
		[ 2., 2., 4., 0.]])]

>>> np.hsplit(a,(3,4)) # Split a after the third and the fourth column
[array([[ 9., 5., 6.],
		[ 1., 4., 9.]]),
 array([[ 3.],
		[ 2.]]),
 array([[ 6., 8., 0., 7., 9., 7., 2., 7.],
		[ 2., 1., 0., 6., 2., 2., 4., 0.]])]

Fancy indexing and index tricks

>>> a = np.arange(12)**2 # the first 12 square numbers
>>> i = np.array( [ 1,1,3,8,5 ] ) # an array of indices

>>> a[i] # the elements of a at the positions i
array([ 1, 1, 9, 64, 25])

>>> j = np.array( [ [ 3, 4], [ 9, 7 ] ] ) # a bidimensional array of indices

>>> a[j] # the same shape as j
array([[ 9, 16],
	   [81, 49]])

>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
	   [ 4, 5, 6, 7],
	   [ 8, 9, 10, 11]])

>>> i = np.array( [ [0,1], [1,2] ] ) # indices for the first dim of a

>>> j = np.array( [ [2,1], [3,3] ] ) # indices for the second dim

>>> a[i,j] # i and j must have equal shape
array([[ 2, 5],
	   [ 7, 11]])
>>> a = np.arange(12).reshape(3,4)
>>> b = a > 4
>>> b # b is a boolean with a's shape
array([[False, False, False, False],
	   [False, True, True, True],
	   [ True, True, True, True]])
>>> a[b] # 1d array with the selected elements
array([ 5, 6, 7, 8, 9, 10, 11])

>>> a[b] = 0 # All elements of 'a' higher than 4 become 0
>>> a
array([[0, 1, 2, 3],
       [4, 0, 0, 0],
	   [0, 0, 0, 0]])

Mandelbrot set

import numpy as np
import matplotlib.pyplot as plt

>>> def mandelbrot( h,w, maxit=20 ):
	 """Returns an image of the Mandelbrot fractal of size (h,w)."""
	y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ]
	c = x+y*1j
	z = c
	divtime = maxit + np.zeros(z.shape, dtype=int)
    
	for i in range(maxit):
		z = z**2 + c
		diverge = z*np.conj(z) > 2**2 # who is diverging
		div_now = diverge & (divtime==maxit) # who is diverging now
		divtime[div_now] = i # note when
		z[diverge] = 2 # avoid diverging too much
        
	return divtime

>>> plt.imshow(mandelbrot(400,400))
>>> plt.show()

The ix_() function

>>> a = np.array([2,3,4,5])
>>> b = np.array([8,5,4])
>>> c = np.array([5,4,6,8,3])

>>> ax,bx,cx = np.ix_(a,b,c)
>>> ax
array([[[2]],
	   [[3]],
	   [[4]],
	   [[5]]])

>>> bx
array([[[8],
		[5],
		[4]]])

>>> cx
array([[[5, 4, 6, 8, 3]]])

>>> ax.shape, bx.shape, cx.shape
((4, 1, 1), (1, 3, 1), (1, 1, 5))

>>> result = ax+bx*cx

>>> result
array([[[42, 34, 50, 66, 26],
		[27, 22, 32, 42, 17],
		[22, 18, 26, 34, 14]],
	   [[43, 35, 51, 67, 27],
		[28, 23, 33, 43, 18],
		[23, 19, 27, 35, 15]],
	   [[44, 36, 52, 68, 28],
		[29, 24, 34, 44, 19],
		[24, 20, 28, 36, 16]],
	   [[45, 37, 53, 69, 29],
		[30, 25, 35, 45, 20],
		[25, 21, 29, 37, 17]]])

>>> result[3,2,4]
17
>>> a[3]+b[2]+c[4]
17

Linear algebra

import numpy as np

>>> a = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> print(a)
	[[ 1. 2.]
	 [ 3. 4.]]
    
>>> a.transpose()
array([[ 1., 3.],
	   [ 2., 4.]])

>>> np.linalg.inv(a)
array([[-2. , 1. ],
	   [ 1.5, -0.5]])

>>> u = np.eye(2) # unit 2x2 matrix; "eye" represents "I"
>>> u
array([[ 1., 0.],
	   [ 0., 1.]])

>>> j = np.array([[0.0, -1.0], [1.0, 0.0]])
>>> j @ j # matrix product
array([[-1., 0.],
	   [ 0., -1.]])

>>> np.trace(u) # trace
2.0

>>> y = np.array([[5.], [7.]])
>>> np.linalg.solve(a, y)
array([[-3.],
	   [ 4.]])

>>> np.linalg.eig(j)
(array([ 0.+1.j, 0.-1.j]),
 array([[ 0.70710678+0.j , 0.70710678-0.j ],
		[ 0.00000000-0.70710678j, 0.00000000+0.70710678j]]))

Histograms

import numpy as np
import matplotlib.pyplot as plt
# Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
>>> mu, sigma = 2, 0.5
>>> v = np.random.normal(mu,sigma,10000)

>>> # Plot a normalized histogram with 50 bins
>>> plt.hist(v, bins=50, density=1) # matplotlib version (plot)
>>> plt.show()

>>> # Compute the histogram with numpy and then plot it
>>> (n, bins) = np.histogram(v, bins=50, density=True) # NumPy version (no plot)
>>> plt.plot(.5*(bins[1:]+bins[:-1]), n)
>>> plt.show()

Comments