Rémi Flamary

Site web professionel

Introduction à Python pour le calcul scientifique

Ce support est vouè à être présenté à l'oral en exécutant le code au fur et à mesure avec des examples.

Pour une vraie introduction détaillée je recommande fortement le cours suivant: Cours Python 3 pour la programmation scientifique

Installation de Python

  • Python est disponible librement sous Windows/Linux/MacOSX

  • Télécharger l'environement Python 3 sur le site de Anaconda.

  • Installer Python 3

Spyder VS Notebook

Spyder

  • Éditeur Python dédié au calcul scientifique
  • Interface trés similaire à Matlab
  • Workspace + debugger

Notebook

  • Edition directement dans le navigateur
  • Insertion directe de texte
  • Parfait pour démonstration
  • Expot des notebook en PDF, HTML, ...

Je recommande Spyder pour faire du code propre et réutilisable. L'accès aux variables en mémoire est un plus pour débugger.

Spyder

image.png

Utilisation de #%% pour séparer des blocks de code

Jupyter notebook

image.png

Introduction rapide à Python

Types de base

In [1]:
txt="texte, chaine de caractère ' "
i=10 # entier
f=10.0 # flottant

txt,i,f
Out[1]:
("texte, chaine de caractère ' ", 10, 10.0)

 Listes et tuples

In [2]:
liste= ['liste',1,10,1e10] # contient n'importe quel type
tup= ('liste','nom','modifiable')

#tup
#liste.append('truc ajouté')
liste[1]
#liste
Out[2]:
1

 Dictionnaire

In [3]:
dic={'cle':'valeur',0:'valeur pour cle 0'}

#dic['nouvelle cle']=10
dic['cle']

dic2={'bonjour':'hello','monde':'world'}

lst1=['bonjour','monde']

for mot in lst1:
    print(dic2[mot])
hello
world

Impression

In [4]:
print(10)
print('du texte')
10
du texte

Formatage

In [5]:
txt='texte'
i=10 # entier
f=1.2e-3 # flottant

print("txt='{}',i={},f={}".format(txt,i,f))
print("txt='{:>10s}',i={:04},f={:e}".format(txt,i,f))
txt='texte',i=10,f=0.0012
txt='     texte',i=0010,f=1.200000e-03

Test et boucles

 Tests

In [6]:
v=5
if v>5:
    print('v>5') # block de code un tab souvent egela à 4 espaces
elif v==5: # test d'égalité ==
    print('v=5')
else:
    print('v<5') # Attention on ne mélange pas les espaces et les tab!

v=5

 Boucle for

In [7]:
lst=range(5)
#lst=[1,10,25]

for i in lst:
    print('i={}'.format(i))
i=0
i=1
i=2
i=3
i=4

Modules pour le calcul scientifique

  • Numpy (calcul vectoriel et matriciel)
  • Scipy (fonctions spéciale, traitement du signal, optimisation)
  • Matplotlib/pylab (visualisation, tracé de courbes)

On importe ces modules au début du scipt/notebook:

In [8]:
import numpy as np
import scipy as sp
import pylab as pl

Aide sur les modules

Ctrl+i dans spyder ouvre la doc pour une fonction

Ou directement dans le terminal:

In [9]:
help(np.zeros)
Help on built-in function zeros in module numpy:

zeros(...)
    zeros(shape, dtype=float, order='C')

    Return a new array of given shape and type, filled with zeros.

    Parameters
    ----------
    shape : int or tuple of ints
        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
    dtype : data-type, optional
        The desired data-type for the array, e.g., `numpy.int8`.  Default is
        `numpy.float64`.
    order : {'C', 'F'}, optional, default: 'C'
        Whether to store multi-dimensional data in row-major
        (C-style) or column-major (Fortran-style) order in
        memory.

    Returns
    -------
    out : ndarray
        Array of zeros with the given shape, dtype, and order.

    See Also
    --------
    zeros_like : Return an array of zeros with shape and type of input.
    empty : Return a new uninitialized array.
    ones : Return a new array setting values to one.
    full : Return a new array of given shape filled with value.

    Examples
    --------
    >>> np.zeros(5)
    array([ 0.,  0.,  0.,  0.,  0.])

    >>> np.zeros((5,), dtype=int)
    array([0, 0, 0, 0, 0])

    >>> np.zeros((2, 1))
    array([[ 0.],
           [ 0.]])

    >>> s = (2,2)
    >>> np.zeros(s)
    array([[ 0.,  0.],
           [ 0.,  0.]])

    >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
    array([(0, 0), (0, 0)],
          dtype=[('x', '<i4'), ('y', '<i4')])

Numpy

Objet np.array

typedef struct PyArrayObject {
 PyObject_HEAD
 char *data; // .data
 int nd; //
 npy_intp *dimensions; // .shape
 npy_intp *strides;  // .strides
 PyObject *base;
 PyArray_Descr *descr;
 int flags;
 PyObject *weakreflist;
 } PyArrayObject;
In [10]:
M=np.array([[1,2,3],[4,5,6]])
M
Out[10]:
array([[1, 2, 3],
       [4, 5, 6]])

Propriétés

In [11]:
M.shape # dtype, 
Out[11]:
(2, 3)

Fonctions sum,max,min,std

In [12]:
#help(M.sum)
M.sum(1)
Out[12]:
array([ 6, 15])

Numpy

Creation de vecteurs:

In [13]:
m,n=2,3 # tailles

v0=np.zeros(n)
v1=np.ones(n)
vr=np.arange(n)
va=np.random.randn(n) # vecteur aléatoire gaussien

print('shape={}'.format(v0.shape))
print('v0={}\nv1={}\nvr={}\nva={}'.format(v0,v1,vr,va))
shape=(3,)
v0=[0. 0. 0.]
v1=[1. 1. 1.]
vr=[0 1 2]
va=[ 0.3410162   0.02050334 -1.82021007]

Numpy

Creation de matrices

In [14]:
m,n=2,3 # tailles

M0=np.zeros((m,n))
M1=np.ones((m,n))
Ma=np.random.randn(m,n) # vecteur aléatoire gaussien

print('shape={}'.format(M0.shape))
print('M0:\n{}\nM1:\n{}\nMa:\n{}'.format(M0,M1,Ma))
shape=(2, 3)
M0:
[[0. 0. 0.]
 [0. 0. 0.]]
M1:
[[1. 1. 1.]
 [1. 1. 1.]]
Ma:
[[-0.61904318 -0.26379544 -0.89636392]
 [ 0.98897004  0.04198321 -0.72572295]]

Numpy

Indexage et slices

In [15]:
m,n=3,4 # tailles
M=np.arange(m*n).reshape((m,n))
print('M:\n{}'.format(M))

c=M[:,1] # selction de colonne
l=M[0,:] # selection de ligne

print('c={}\nl={}'.format(c,l))



M:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
c=[1 5 9]
l=[0 1 2 3]
In [16]:
M[:,[0,2]]
np.arange(m*n)
Out[16]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

Numpy

Calculs numériques

Tous les opérateur de caluls sur les vecteurs/matrice se font point à point.

In [17]:
M=np.array([[1,2,3],[4,5,6]])
O=np.ones((2,3))
M+3*O
Out[17]:
array([[4., 5., 6.],
       [7., 8., 9.]])

Fonctions

In [18]:
np.exp(M) # np.log, .....
Out[18]:
array([[  2.71828183,   7.3890561 ,  20.08553692],
       [ 54.59815003, 148.4131591 , 403.42879349]])

Somme de tableaux de tailles différentes

In [19]:
v1=np.arange(4)
v2=np.ones(3)
v1.shape,v1,v2
Out[19]:
((4,), array([0, 1, 2, 3]), array([1., 1., 1.]))
In [20]:
v1.reshape((1,4)),v1[None,:],v1[:,None]
Out[20]:
(array([[0, 1, 2, 3]]),
 array([[0, 1, 2, 3]]),
 array([[0],
        [1],
        [2],
        [3]]))
In [21]:
v1[:,None]+v2[None,:]
Out[21]:
array([[1., 1., 1.],
       [2., 2., 2.],
       [3., 3., 3.],
       [4., 4., 4.]])

Numpy

Chargement de données en mémoire

In [22]:
data=np.load('../tds_ml/digits.npz')
print(list(data))
['xt', 'yt', 'y', 'x']
In [23]:
# charge les données
x=data['x']
print(x)
[[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]

Numpy

Algebre lineaire

Multiplication matricielle

In [24]:
M=np.array([[1,2,3],[4,5,6]])
v=np.array([1,1,1])

M.dot(v)
#v[:2].dot(M)
Out[24]:
array([ 6, 15])

opérations d'algèbre linéaire dans le module np.linalg et sp.linalg pour les opérations plus complexes.

Exercice

$$\mathbf{u}=\begin{bmatrix}1\\2\\3\end{bmatrix},\quad \mathbf{v}=\begin{bmatrix}1\\1\\1\end{bmatrix},\quad \mathbf{A}=\begin{bmatrix}1& -1& 0\\ -1& 1& -1\\ 0& -1&1\end{bmatrix},\quad \mathbf{B}=\begin{bmatrix}1& 2\\ 3&4\\ 5&6\end{bmatrix} $$
  1. Stocker les matrices et vecteurs $\mathbf{u},\mathbf{v},\mathbf{A},\mathbf{B}$ en mémoire (np.array)
  2. Calculer les valeurs suivantes
$$\def\u{\mathbf{u}}\def\v{\mathbf{v}}\def\A{\mathbf{A}}\def\B{\mathbf{B}}\u^\top\u\quad\quad\qquad \u^\top\v\quad\qquad\qquad\quad\quad \u^\top\A\v$$$$\u\u^\top\quad\qquad\qquad \u\v^\top\qquad\qquad\quad \A\A $$$$\A\u\quad\qquad\qquad\A\v\qquad\qquad\quad\B^\top\u\quad\qquad\qquad\A\B$$

vous aurez besoind des fonctions np.dot,dp.outer.

In [ ]: