import numpy as np
import matplotlib.pyplot as plt
from numpy import array, cos, sin
%matplotlib inline
for i in range(20):
print(i)
if i > 30:
break
else:
print("maximum number of iteration reached")
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 not broken
assigment: a=b=c=0
, a,b = b,a
, a=0
does not return anything
a = b = 3
print(a,b)
3 3
a = b = []
a is b
True
a,b = 3,4
print(a,b)
3 4
a,b = b,a
print(a,b)
4 3
a,b,c,d = 1,2,3,"asf"
((a,b),c) = ((2,3),4)
(a = 2) == 3 # illegal!
False
1/0
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-61-05c9758a9c21> in <module>() ----> 1 1/0 ZeroDivisionError: division by zero
$#
File "<ipython-input-62-921cc23c5c50>", line 1 $# ^ SyntaxError: invalid syntax
1/0
$#
File "<ipython-input-63-1d81501595aa>", line 2 $# ^ SyntaxError: invalid syntax
array(1)/array(0)
/Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/ipykernel/__main__.py:1: RuntimeWarning: divide by zero encountered in true_divide if __name__ == '__main__':
inf
1./0.
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-65-3543596c47ff> in <module>() ----> 1 1./0. ZeroDivisionError: float division by zero
multiple comparison: 0 < x < 1
x = .5
print(0 < x < 1)
print( (0<x) < 1)
True False
deep copying [[2,3]]
, L*3
?
in
, not in
for belonging to a list
L = [1,2,3,3,4]
5 in L
L.index(3)
2
7 not in L
True
list comprehension: with guard, multiple for
inside
L
[1, 2, 3, 3, 4]
[x**2 for x in L]
[1, 4, 9, 9, 16]
[(i,j) for i in range(3) for j in range(2)]
[[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]
array([i*j for i in range(3) for j in range(2)]).reshape((3,2))
array([[0, 0], [0, 1], [0, 2]])
[x**2 for x in ["a", b] if type(x) == int]
[4]
tuples
t = (2,3)
t[0]
2
t[0] = 1
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-85-0a69537257d5> in <module>() ----> 1 t[0] = 1 TypeError: 'tuple' object does not support item assignment
strides, negative strides
slicing like a butcher: meaning of L[n:]
, L[-n:]
, etc. L[::-n]
, L[100:200]
empty, replace chunks in a list
L
[1, 2, 3, 3, 4]
L[100:200]
[]
L[100]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-88-78da2f882365> in <module>() ----> 1 L[100] IndexError: list index out of range
a = array(L)
a[100:200]
array([], dtype=int64)
zip
L
[1, 2, 3, 3, 4]
L1 = [10,20,30]
z = list(zip(L,L1))
print(z)
[(1, 10), (2, 20), (3, 30)]
L = [1, 2, 3, 3, 4]
L.append(L1)
print(L)
[1, 2, 3, 3, 4, [10, 20, 30]]
[x for x,y in z]
[1, 2, 3]
el = list(enumerate(L))
print(el)
[(0, 1), (1, 2), (2, 3), (3, 3), (4, 4)]
[i for i,x in el if x == 3]
[2, 3]
keys
, items
, values
d = {'a': 3, 'b': 4}
d['a']
3
d['b']
4
x = 'a'
d[x] = 100
person1 = {'surname': 'Verdier', 'name': "Olivier"}
Iterative algorithms
x = 1
max_iter = 100
for i in range(max_iter):
x = x**2
if x > 100:
break
else:
print("Algorithm did not converge in %s steps" % max_iter)
Algorithm did not converge in 100 steps
plot
labels and legends
xs = linspace(0,1,200)
plot(xs, cos(xs), label='cos')
plot(xs, sin(xs), label='sin')
legend()
savefig('sincos.pdf')
Docstrings! (triple quotes)
def my_function():
"""
my_function is a super function
more information here
that's enough
"""
print("Hi! How are you?")
my_function?
Return multiple values
Functions always return None
Function arguments: named, default, star operations (varargs)
def power_function(a,b):
return a**b
power_function(2,3)
8
param_list = [2,3]
power_function(*param_list)
8
power_function(array([2,3]), array([3,4]))
array([ 8, 81])
power_function(*[3,4])
81
param_dict = { 'b': 3, 'c': 2}
power_function(**param_dict)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-124-4d23a083342e> in <module>() ----> 1 power_function(**param_dict) TypeError: power_function() got an unexpected keyword argument 'c'
power_function??
power_function(b=3, a=2)
8
b, a = 2, 3
power_function(a=b, b=a)
def nice_function(a, b=3):
return a**b
nice_function(2)
8
nice_function(2, b=5)
32
nice_function(2,5)
32
def super_function(a,b,*args, **kwargs):
print(args)
print(kwargs)
super_function(2,3,"hello",c=4,d=10)
('hello',) {'c': 4, 'd': 10}
super_function(2,a=4,4,b=10)
File "<ipython-input-134-e84df2085f0a>", line 1 super_function(2,a=4,4,b=10) ^ SyntaxError: non-keyword arg after keyword arg
def append_function(a, b=[]):
b.append(a)
return b
append_function(3,[4,5,6])
[4, 5, 6, 3]
append_function(3)
[3]
append_function(4)
[3, 4]
closure example
def sin_freq(freq, x):
return sin(2*pi*freq*x)
def get_sin_with_freq(freq):
def sin_freq(x):
return sin(2*pi*freq*x)
return sin_freq
sin10 = get_sin_with_freq(10)
xs = linspace(0,1,200)
plot(xs, sin10(xs))
[<matplotlib.lines.Line2D at 0x106a74048>]
Generators: enumerate
, range
, reversed
def divide(a,b):
if b == 0:
raise Exception("Oops, b is zero")
return a/b
divide(3,4)
0.75
divide(3,0)
--------------------------------------------------------------------------- Exception Traceback (most recent call last) <ipython-input-150-24bf8d716600> in <module>() ----> 1 divide(3,0) <ipython-input-148-11371656a320> in divide(a, b) 1 def divide(a,b): 2 if b == 0: ----> 3 raise Exception("Oops, b is zero") 4 return a/b Exception: Oops, b is zero
Namespaces, import
, %run
, etc.
import example
example.J
1j
example.imported_function(2.)
200.0
%run example.py
imported_function(2.)
200.0
from example import bisect as example_bisect
class Example:
pass
example = Example()
example.bisect = example_bisect
from example import *
import example1
import example2
example1.imported_function
example2.imported_function
--------------------------------------------------------------------------- ImportError Traceback (most recent call last) <ipython-input-102-d85a77517064> in <module>() ----> 1 import example1 2 import example2 3 example1.imported_function 4 example2.imported_function ImportError: No module named 'example1'
a = 0
a = 1
example = 10
import example as ex
ex.imported_function
<function example.imported_function>
array length is fixed: v[:2] = array([1])
, or v.append
flags?
Boolean arrays: mask, example with rand(10,10)
and capping at .5
M = np.random.randn(5,5)
print(M)
[[-0.45771511 -0.44600716 -0.0963087 0.36646952 -0.35648425] [-0.532434 0.19209479 0.83525092 -0.24639756 -0.61241575] [-0.82984776 -1.21664042 0.89142928 0.47979501 -0.30452319] [ 0.48553935 -1.62094851 0.81100656 0.05521396 -0.74060706] [ 1.54060755 -0.07426069 -0.40557241 -1.25481997 -1.77014925]]
mask = M > 0
print(mask)
[[False False False True False] [False True True False False] [False False True True False] [ True False True True False] [ True False False False False]]
M[mask] = 100
M
array([[ -4.57715111e-01, -4.46007163e-01, -9.63087029e-02, 1.00000000e+02, -3.56484245e-01], [ -5.32434001e-01, 1.00000000e+02, 1.00000000e+02, -2.46397558e-01, -6.12415752e-01], [ -8.29847762e-01, -1.21664042e+00, 1.00000000e+02, 1.00000000e+02, -3.04523194e-01], [ 1.00000000e+02, -1.62094851e+00, 1.00000000e+02, 1.00000000e+02, -7.40607061e-01], [ 1.00000000e+02, -7.42606888e-02, -4.05572411e-01, -1.25481997e+00, -1.77014925e+00]])
M[M<0] = -100
print(M)
[[-100. -100. -100. 100. -100.] [-100. 100. 100. -100. -100.] [-100. -100. 100. 100. -100.] [ 100. -100. 100. 100. -100.] [ 100. -100. -100. -100. -100.]]
array comparison
M
array([[-100., -100., -100., 100., -100.], [-100., 100., 100., -100., -100.], [-100., -100., 100., 100., -100.], [ 100., -100., 100., 100., -100.], [ 100., -100., -100., -100., -100.]])
M == M
array([[ True, True, True, True, True], [ True, True, True, True, True], [ True, True, True, True, True], [ True, True, True, True, True], [ True, True, True, True, True]], dtype=bool)
if (M == M).all():
print("M is equal to itself!")
M is equal to itself!
vectorize
example with sign
?
def sign(x):
if x < 0:
return -1
else:
return 1
data = np.arange(5)-2
data
array([-2, -1, 0, 1, 2])
vsign = np.vectorize(sign)
vsign(data)
array([-1, -1, 1, 1, 1])
sign(data)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-176-783031542db4> in <module>() ----> 1 sign(data) <ipython-input-173-888533a22840> in sign(x) 1 def sign(x): ----> 2 if x < 0: 3 return -1 4 else: 5 return 1 ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
reshape with -1
solve
!!
M = array([[1.,2.], [3.,4.]])
V = array([2.,3.])
print(M, V)
[[ 1. 2.] [ 3. 4.]] [ 2. 3.]
x = solve(M, V) # solves dot(M,x) == V
allclose(dot(M,x), V)
True
No direct array comparision, use all
, A < .75 & A > .25
Views?
Broadcasting!
print(M, V)
[[ 1. 2.] [ 3. 4.]] [ 2. 3.]
M * V
array([[ 2., 6.], [ 6., 12.]])
Objects: example with Complex
, __init__
, __add__
.
class Complex:
def __init__(self, x, y):
print("init!")
self.r = x
self.i = y
def abs(self):
return np.sqrt(self.r**2 + self.i**2)
def __add__(self, zz):
return Complex(self.r + zz.r, self.i + zz.i)
def __str__(self):
return "%s + %s J" % (self.r, self.i)
def __repr__(self):
return "Complex({},{})".format(self.r, self.i)
z = Complex(1.,2.)
init!
z2 = Complex(10., 20.)
z.__add__(z2)
init! init!
Complex(11.0,22.0)
z + z2
init!
11.0 + 22.0 J
z * z2
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-202-a1db40b12982> in <module>() ----> 1 z * z2 TypeError: unsupported operand type(s) for *: 'Complex' and 'Complex'
z.abs()
2.2360679774997898
z.r,z.i
(1.0, 2.0)
z.__dict__
{'i': 2.0, 'r': 1.0}
def big_loop():
s = 0
for i in range(10000):
s = s + np.sqrt(i)
%prun big_loop()
%timeit big_loop()
100 loops, best of 3: 12.7 ms per loop
%prun?
import datetime
tic = datetime.datetime.now()
big_loop()
toc = datetime.datetime.now()
print(toc - tic)
0:00:00.013855
def get_grid(nh,nv):
x = np.linspace(-2,.8,nh)
y = np.linspace(-1.4,1.4,nv)
return np.meshgrid(x,y,indexing='ij')
def mandel_py(w,h,maxit=20):
# prepare initial points
x, y = get_grid(w,h)
c = x+y*1j
# where to store output
output = np.zeros(c.shape, dtype=int) + maxit
for i in range(h): # loop 1
for j in range(w): # loop 2
z = 0.
c0 = c[i,j]
for k in range(maxit): # loop 3!!
z = z**2 + c0
if z*z.conjugate() > 4.0:
output[i, j] = k
break
return output.T
nb.jit(nopython=True)(mandel_py)(200,200)
--------------------------------------------------------------------------- TypingError Traceback (most recent call last) <ipython-input-264-f046d1b4de87> in <module>() ----> 1 nb.jit(nopython=True)(mandel_py)(200,200) /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws) 169 assert not kws 170 sig = tuple([self.typeof_pyval(a) for a in args]) --> 171 return self.compile(sig) 172 173 def inspect_llvm(self, signature=None): /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/dispatcher.py in compile(self, sig) 346 self.py_func, 347 args=args, return_type=return_type, --> 348 flags=flags, locals=self.locals) 349 350 # Check typing error if object mode is used /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library) 635 pipeline = Pipeline(typingctx, targetctx, library, 636 args, return_type, flags, locals) --> 637 return pipeline.compile_extra(func) 638 639 /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in compile_extra(self, func) 356 raise e 357 --> 358 return self.compile_bytecode(bc, func_attr=self.func_attr) 359 360 def compile_bytecode(self, bc, lifted=(), lifted_from=None, /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in compile_bytecode(self, bc, lifted, lifted_from, func_attr) 365 self.lifted_from = lifted_from 366 self.func_attr = func_attr --> 367 return self._compile_bytecode() 368 369 def compile_internal(self, bc, func_attr=DEFAULT_FUNCTION_ATTRIBUTES): /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in _compile_bytecode(self) 622 623 pm.finalize() --> 624 return pm.run(self.status) 625 626 /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in run(self, status) 248 # No more fallback pipelines? 249 if is_final_pipeline: --> 250 raise patched_exception 251 # Go to next fallback pipeline 252 else: /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in run(self, status) 240 for stage, stage_name in self.pipeline_stages[pipeline_name]: 241 try: --> 242 res = stage() 243 except _EarlyPipelineCompletion as e: 244 return e.result /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in stage_nopython_frontend(self) 453 self.args, 454 self.return_type, --> 455 self.locals) 456 457 with self.fallback_context('Function "%s" has invalid return type' /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/compiler.py in type_inference_stage(typingctx, interp, args, return_type, locals) 749 infer.seed_type(k, v) 750 --> 751 infer.build_constraint() 752 infer.propagate() 753 typemap, restype, calltypes = infer.unify() /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/typeinfer.py in build_constraint(self) 492 for blk in utils.itervalues(self.blocks): 493 for inst in blk.body: --> 494 self.constrain_statement(inst) 495 496 def propagate(self): /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/typeinfer.py in constrain_statement(self, inst) 649 def constrain_statement(self, inst): 650 if isinstance(inst, ir.Assign): --> 651 self.typeof_assign(inst) 652 elif isinstance(inst, ir.SetItem): 653 self.typeof_setitem(inst) /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/typeinfer.py in typeof_assign(self, inst) 689 src=value.name, loc=inst.loc)) 690 elif isinstance(value, (ir.Global, ir.FreeVar)): --> 691 self.typeof_global(inst, inst.target, value) 692 elif isinstance(value, ir.Arg): 693 self.typeof_arg(inst, inst.target, value) /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/numba/typeinfer.py in typeof_global(self, inst, target, gvar) 754 else: 755 raise TypingError("Untyped global name '%s'" % gvar.name, --> 756 loc=inst.loc) 757 758 def typeof_expr(self, inst, target, expr): TypingError: Failed at nopython (nopython frontend) Untyped global name 'get_grid' File "<ipython-input-253-ff821fe7c6f4>", line 3
def mandel_np(w,h,maxit=20):
# prepare initial points
x, y = get_grid(w,h)
c = x+y*1j
# where to store output
output = np.zeros_like(c, dtype=int) + maxit
z = np.zeros_like(c)
for k in range(maxit):
z = z**2 + c
mask = z*z.conjugate() <= 4.0
output[mask] = k
return output.T
plt.imshow(mandel_py(200,200))
<matplotlib.image.AxesImage at 0x109c2bd30>
%timeit mandel_np(200,200)
100 loops, best of 3: 9.83 ms per loop
/Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/ipykernel/__main__.py:10: RuntimeWarning: overflow encountered in multiply /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/ipykernel/__main__.py:10: RuntimeWarning: invalid value encountered in multiply /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/ipykernel/__main__.py:9: RuntimeWarning: overflow encountered in square /Users/olivier/anaconda/envs/python3/lib/python3.4/site-packages/ipykernel/__main__.py:9: RuntimeWarning: invalid value encountered in square
zeros_like?
%timeit mandel_py(200,200)
1 loops, best of 3: 703 ms per loop
import numba as nb
def mandel_raw(grid, output,maxit):
for i in range(grid.shape[0]): # loop 1
for j in range(grid.shape[1]): # loop 2
z = 0.+0j
c0 = grid[i,j]
for k in range(maxit): # loop 3!!
z = z**2 + c0
if z.real*z.real + z.imag*z.imag > 4.0:
output[i, j] = k
break
mandel_nb = nb.jit('void(c16[:,:],i8[:,:],i8)', nopython=True)(mandel_raw)
def mandel_opt(w,h,maxit=20):
x, y = get_grid(w,h)
grid = x+y*1j
output = np.zeros_like(grid, dtype=int) + maxit
mandel_nb(grid,output,maxit)
return output.T
%timeit mandel_opt(200,200)
100 loops, best of 3: 2.13 ms per loop
plt.imshow(mandel_opt(200,200))
<matplotlib.image.AxesImage at 0x1099f1208>
imshow(mandel_py(200,200))
<matplotlib.image.AxesImage at 0x109df5160>
%prun mandel_py(200,200)