In [138]:
%matplotlib inline
%config InlineBackend.figure_format = 'png'
matplotlib.rcParams['figure.figsize'] = (4,4)
matplotlib.rcParams['xtick.labelsize'] = 35
matplotlib.rcParams['ytick.labelsize'] = 35
matplotlib.rcParams['font.size'] = 35
matplotlib.rcParams['axes.labelsize'] = 50
matplotlib.rcParams['axes.facecolor'] = 'white'
matplotlib.rcParams['axes.edgecolor'] = 'black'
matplotlib.rcParams['axes.linewidth'] = 5
matplotlib.rcParams['lines.linewidth'] = 10.0 # line width in points
#matplotlib.rcParams['lines.color'] = 'blue' # has no affect on plot(); see axes.prop_cycle
matplotlib.rcParams['lines.markersize'] = 8 #
Unarguably the most important python library for scientists. Remember this?
It is so huge, we will not even try to cover it in any detail here. What follows is more of an unboxing video rather than a product review.
Sebastian made a much more comprehensive presentation. See it here: https://github.com/MPIDS/Python-Course/blob/master/03-numpy-scipy/talks/basic-numpy.ipynb
In [1]:
import numpy as np # canonicalw ay of importing it
In [6]:
a = np.array([1,2,3,4,5,6,7,8,9,10]) #lists with special powers
# or we could just do:
b = np.arange(1,11,1)
a == b
Out[6]:
You guessed right: arithmetic operations with numpy arrays happen elementwise:
In [9]:
print(a**2)
print(a+b)
In [19]:
x = np.arange(0,1000,1)
In [20]:
%%timeit
[i/2 for i in x]
In [21]:
%%timeit
x/2
Try your hand on other operators:
>, <, /
np.sin, np.cos, np.round,np.log, np.sqrt...
In [14]:
arr = np.array(5)
# although 0-d arrays are sometimes a bit special :(
print(arr)
print('The dimension is:', arr.ndim)
print('The shape is:', arr.shape)
In [22]:
arr = np.array([4, 5, 6])
print(arr)
print('The dimension is:', arr.ndim)
print('The shape is:', arr.shape)
In [23]:
arr = np.array([[1, 2],
[3, 4],
[5, 6]])
print(arr)
print('The dimension is:', arr.ndim)
print('The shape is:', arr.shape)
In [37]:
print(np.zeros((3,6)))
print(np.ones((3,6)))
print(np.eye(4))
print(np.eye(4, k = 1))
print(np.diag([1,2,3,4]))
print(np.zeros_like(np.diag([1,2,3,4])))
print(np.linspace(0,1,10))
There are so many more:
np.arange
np.tri
np.triu
np.tril
In [174]:
x = 1000 # flag width
y = 1000 # flag height
bw = 100 # width of the cross and slashes
flag = np.zeros((x, y), dtype = bool) # a white canvas (white==0)
cross = np.zeros_like(flag)
cross[y//2-bw:y//2+bw,:] = 1 # The horizontal stroke
cross[:,y//2-bw:y//2+bw] = 1 # The vertical stroke
slashes = np.ones_like(flag, dtype = bool) # a black canvas
slash_left = np.logical_not(np.triu(slashes, k = bw) | np.tril(slashes, k = -bw))
slash_right = slash_left[::-1, :] # right slash by inverting the x axis
squarejack = (cross | slash_left | slash_right) # numpy logical or to combine all
In [158]:
def show(arr2D):
"""shows a 2D numpy array"""
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
h,w = arr2D.shape
ax.set_aspect(w/h)
ax.grid('off')
ax.axis('off')
ax.imshow(arr2D, interpolation='nearest')
In [175]:
show(squarejack)
In [176]:
board = np.ones((16,16))
board[::2,1::2] = 0
board[1::2,0::2] = 0
show(board)
np.random.rand(d0,d1,..)
np.random.randn(d0,d1,..)
np.random.uniform(low, high, size = (d0,d1,..))
In [55]:
normdistarr = np.random.normal(loc = 2, scale = 0.3, size = 10000)
print(normdistarr.mean())
print(normdistarr.var())
print(normdistarr.ptp())
print(normdistarr.max())
print(normdistarr.min())
They can also be done on only one axis
In [56]:
normdist2D = np.random.normal(loc = 2, scale = 0.3, size = (10, 1000))
print(normdist2D.mean(axis = 1))
print(normdist2D.var(axis = 1))
print(normdist2D.ptp(axis = 1))
print(normdist2D.max(axis = 1))
print(normdist2D.min(axis = 1))
In [57]:
print(normdistarr.argmax())
print(normdistarr.argmin())
In [61]:
arr2d = np.array([[1,2,3],
[4,5,6]])
print(arr2d+3)
print(arr2d+[7,5,3])
In [169]:
x = np.arange(12)
print(x)
print(x.reshape(3,4))
print(x.reshape(3,2,2))
Maybe you want to let numpy infer the size along last dimention, because you are lazy like that:
In [170]:
print(x.reshape(3,-1))
In terms of our venerable SquareJack:
In [177]:
show(squarejack.reshape(500,-1))
In [178]:
show(squarejack)
np.arange
np.concatenate
np.tile
In [179]:
show(np.tile(squarejack,4))
In [180]:
show(np.concatenate((squarejack, 1-squarejack)))
Picking a single element from an array requires an integer along each dimension
In [77]:
arr = np.arange(10).reshape(2, 5)
print(arr)
In [78]:
print(arr[0, 3])
print(arr[1, 2])
Somewhat confusing way of choosing more than one element:
In [82]:
print(arr[(0,1), (3,2)]) # arr[(x1, x2, x3,..), (y1, y2, y3, ...)]
[start:stop:step]
[start:stop] ==[start:stop:1]
[start:] == [start:END:1]
[::step] == [BEGIN:END:step]
In [92]:
arr = np.arange(12).reshape(3, 4)
print(arr)
In [75]:
arr[0:2,1:4]
Out[75]:
In [83]:
arr[:, 2:4]
Out[83]:
one can reverse arrays with negative step
In [93]:
arr[::-1, ::-1]
Out[93]:
Messing more with SquareJack:
In [183]:
show(squarejack[:500,:500]) # Top left corner
In [187]:
show(squarejack[500:0:-1,0:500]) # Top left corner, flipped lengthways
In [188]:
show(squarejack[500:0:-1,500:0:-1]) # Top left corner, flipped both ways
In [244]:
arr = np.arange(12).reshape(2,-1)
In [245]:
arr >7
Out[245]:
In [246]:
arr[arr > 7]
Out[246]:
In [247]:
arr[np.where(arr%2==0)] = 0
In [248]:
np.where(arr%2==0, 0, arr)
Out[248]:
SquareJack gets a taste of grey:
In [249]:
greyjack = squarejack.astype(float)
greyjack[np.where(greyjack[:, :500] < 0.1)] = 0.5
show(greyjack)
matrix multiplication:
In [96]:
x = np.array([[1,2],
[3,4]])
y = np.array([[5],
[6]])
np.dot(x, y) # The matrix product a*v
Out[96]:
A plotting library:
In [97]:
import matplotlib.pyplot as plt
%matplotlib inline
In [98]:
x=np.arange(0,5)
x_sq=x**2
plt.plot(x,x_sq)
Out[98]:
In [99]:
large_array=np.random.randn(1000)
In [100]:
plt.hist(large_array)
Out[100]:
Scipy is a collection of many packages such as:
In [105]:
npts = 1000
error_scale = 0.01
x = np.random.uniform(0,1,npts)
y = 1.5*x + 3 + np.random.normal(scale = error_scale, size = npts)
plt.plot(x, y, 'o')
Out[105]:
In [108]:
from scipy.stats import linregress
In [112]:
slope, intercept, *_ = linregress(x, y)
In [115]:
plt.plot(x, y, 'o', label = "datapoints")
plt.plot(x, slope*x+intercept, '-', label = "linear fit")
plt.legend()
plt.xlabel("x")
plt.ylabel("y")
Out[115]: