Skip to article frontmatterSkip to article content
import numpy as np
from matplotlib import pyplot as plt

contenu de ce notebook (sauter si déjà acquis)

accès aux éléments d’un tableau


accès à un tableau de dimension 1

# le code
tab = np.arange(12)
tab[0] = np.pi
tab[0].dtype, tab[0]
(dtype('int64'), np.int64(3))
# le code
tab1 = tab.astype(np.float64)
tab1[0] = np.pi
tab1[0].dtype, tab1[0]
(dtype('float64'), np.float64(3.141592653589793))

accès à un tableau de dimension > à 1

# le code en dimension 2

tab = np.arange(12).reshape((2, 6))

# première ligne, deuxième colonne
line, col = 0, 1

tab[line, col] = 1000
tab
array([[ 0, 1000, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]])
# le code en dimension 3
tab.resize((2, 3, 2))

# deuxième matrice, troisième ligne, première colonne
mat, line, col = 1, 2, 0

tab[mat, line, col] = 2000
tab
array([[[ 0, 1000], [ 2, 3], [ 4, 5]], [[ 6, 7], [ 8, 9], [2000, 11]]])
[tab.shape[i] for i in range(tab.ndim)]
[2, 3, 2]
tab.shape
(2, 3, 2)

exercices

accès à un élément

  1. créez un tableau des 30 valeurs paires à partir de 2

  2. donnez lui la forme de 2 matrices de 5 lignes et 3 colonnes

  3. accédez à l’élément qui est à la 3ème colonne de la 2ème ligne de la 1ère matrice

  4. obtenez-vous 12 ?

# votre code

exercice

  1. faites un np.ndarray de forme (3, 2, 5, 4)
    avec des nombre aéatoires entiers entre 0 et 100

  2. affichez-le et vous voyez trois groupes et 2 matrices de 5 lignes et 4 colonnes

  3. affichez le nombre des éléments des deux dernières dimensions

# votre code ici

accéder à un sous-tableau (slicing)

différence slicing python et numpy


rappel du slicing Python

# le code
l =  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
print(l[::2])
print(l[1::3])
print(l[::-1])
print(l[:])
[0, 2, 4, 6, 8]
[1, 4, 7]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

slicing en dimension 1

# le code
vec = np.arange(10)
print(vec[::2])
vec[::2] = 100
vec
[0 2 4 6 8]
array([100, 1, 100, 3, 100, 5, 100, 7, 100, 9])

slicing en dimension > à 1 (a)

# le code
tab = np.arange(120).reshape(2, 3, 4, 5)
print(    tab    )
print(    tab[0]    )
print(    tab[0, 1]    )
print(    tab[0, 1, 2]    )
print(    tab[0, 1, :, 3]    )
[[[[  0   1   2   3   4]
   [  5   6   7   8   9]
   [ 10  11  12  13  14]
   [ 15  16  17  18  19]]

  [[ 20  21  22  23  24]
   [ 25  26  27  28  29]
   [ 30  31  32  33  34]
   [ 35  36  37  38  39]]

  [[ 40  41  42  43  44]
   [ 45  46  47  48  49]
   [ 50  51  52  53  54]
   [ 55  56  57  58  59]]]


 [[[ 60  61  62  63  64]
   [ 65  66  67  68  69]
   [ 70  71  72  73  74]
   [ 75  76  77  78  79]]

  [[ 80  81  82  83  84]
   [ 85  86  87  88  89]
   [ 90  91  92  93  94]
   [ 95  96  97  98  99]]

  [[100 101 102 103 104]
   [105 106 107 108 109]
   [110 111 112 113 114]
   [115 116 117 118 119]]]]
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]]

 [[40 41 42 43 44]
  [45 46 47 48 49]
  [50 51 52 53 54]
  [55 56 57 58 59]]]
[[20 21 22 23 24]
 [25 26 27 28 29]
 [30 31 32 33 34]
 [35 36 37 38 39]]
[30 31 32 33 34]
[23 28 33 38]

slicing en dimension > à 1 (b)

tab = np.arange(120).reshape(2, 3, 4, 5)
# en version longue

tab[::, 0, ::, ::]
array([[[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], [[60, 61, 62, 63, 64], [65, 66, 67, 68, 69], [70, 71, 72, 73, 74], [75, 76, 77, 78, 79]]])
# en version courte

tab[:, 0]
array([[[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], [[60, 61, 62, 63, 64], [65, 66, 67, 68, 69], [70, 71, 72, 73, 74], [75, 76, 77, 78, 79]]])

exercices

  1. extrayez du tableau tab précédent
tab = np.arange(120).reshape(2, 3, 4, 5)

la sous-matrice au milieu (i.e. garder deux lignes et 3 colonnes, au centre) des premières matrices de tous les groupes

[[678111213],[666768717273]]\begin{bmatrix}\begin{bmatrix} 6 & 7 & 8\\ 11 & 12 & 13 \end{bmatrix}, \begin{bmatrix} 66 & 67 & 68 \\ 71 & 72 & 73 \end{bmatrix}\end{bmatrix}

indices
on a 2 groupes de 3 matrices de 4 lignes et 5 colonnes

donc

donc

# votre code

les sous-tableaux sont des vues, et non des copies


partage du segment sous-jacent ou non? - avancé

# le code
tab1 = np.arange(10)
print(tab1.base)
None
# le code
tab1 = np.arange(10)
tab2 = tab1.copy()
print(tab2.base)
None
# le code
tab1 = np.array([[1, 2, 3], [4, 5, 6]])
tab2 = tab1[0:2, 0:2] # vue
tab2.base is tab1
True
# le code
tab1 = np.arange(120)
tab2 = tab1.reshape(2, 3, 4, 5) # une vue
tab2.base is tab1
True
# le code
tab1 = np.arange(10).reshape(2, 5)
tab1.base
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

exercice

  1. créez un nouveau tableau formé des deux matrices [(24681012),(141618202224)][\begin{pmatrix} 2 & 4 & 6\\ 8 & 10 & 12 \end{pmatrix}, \begin{pmatrix} 14 & 16 & 18 \\ 20 & 22 & 24 \end{pmatrix}].

  2. affichez sa base

  3. slicez le tableau pour obtenir [(242220181614),(12108642)][\begin{pmatrix} 24 & 22 & 20 \\ 18 & 16 & 14 \\ \end{pmatrix}, \begin{pmatrix} 12 & 10 & 8 \\ 6 & 4 & 2\end{pmatrix}]

  4. affichez la base de la slice

  5. vérifiez que les deux base sont le même objet

# votre code ici

modification des sous-tableaux

exercices avancés pour les rapides

avant d’aborder ces exercices, il existe un utilitaire très pratique (parmi les 2347 que nous n’avons pas eu le temps de couvrir ;); il s’agit de numpy.indices()

commençons par un exemple :

lignes, colonnes = np.indices((3, 5))
lignes
array([[0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [2, 2, 2, 2, 2]])
colonnes
array([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]])

vous remarquerez que dans le tableau qui s’appelle lignes, la valeur dans le tableau correspond au numéro de ligne; dit autrement :

et dans l’autre sens bien sûr

lignes[1, 4]
np.int64(1)
colonnes[1, 4]
np.int64(4)

Pourquoi est-ce qu’on parle de ça me direz-vous ?

Eh bien en guise d’indice, cela vous renvoie à la notion de programmation vectorielle.

Ainsi par exemple si je veux créer une matrice de taille (3,5) dans laquelle M[i, j] == i + j, je ne vais surtout par écrire une boucle for, et au contraire je vais écrire simplement

I, J = np.indices((3, 5))
M = I + J
M
array([[0, 1, 2, 3, 4], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6]])

les rayures

Écrivez une fonction zebre, qui prend en argument un entier n et qui fabrique un tableau carré de coté n, formé d’une alternance de colonnes de 0 et de colonnes de 1.

par exemple pour n=4 on s’attend à ceci

0 1 0 1
0 1 0 1
0 1 0 1
0 1 0 1

le damier

Écrivez une fonction checkers, qui prend en argument la taille n du damier, et un paramètre optionnel qui indique la valeur de la case (0, 0), et qui crée un tableau numpy carré de coté n, et le remplit avec des 0 et 1 comme un damier.

vous devez obtenir par exemple

>>> checkers(4)

array([[1, 0, 1, 0],
       [0, 1, 0, 1],
       [1, 0, 1, 0],
       [0, 1, 0, 1]])

>>> checkers(5, False)

array([[0, 1, 0, 1, 0],
       [1, 0, 1, 0, 1],
       [0, 1, 0, 1, 0],
       [1, 0, 1, 0, 1],
       [0, 1, 0, 1, 0]])
# a vous de jouer

def checkers(n, up_left=True):
    pass
# pour tester

checkers(4)
checkers(5, False)

le super damier par blocs

Il y a beaucoup de méthodes pour faire cet exercice de damier; elles ne vont pas toutes se généraliser pour cette variante du super damier :

Variante écrivez une fonction block_checkers(n, k) qui crée et retourne

c’est-à-dire par exemple pour n=4 et k=3 cela donnerait ceci :

>>> block_checkers(4, 3)

array([[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0]])
#  vous de jouer

def block_checkers(n, k):
    pass
block_checkers(3, 2)
# doit vous donner la figure ci-dessus
# éventuellement avec des False/True au lieu de 0/1

block_checkers(4, 3)

les escaliers

Écrivez une fonction escalier, qui prend en argument un entier n, qui crée un tableau de taille 2n+1, et qui le remplit de manière à ce que:

par exemple

>>> stairs(4)

array([[0, 1, 2, 3, 4, 3, 2, 1, 0],
       [1, 2, 3, 4, 5, 4, 3, 2, 1],
       [2, 3, 4, 5, 6, 5, 4, 3, 2],
       [3, 4, 5, 6, 7, 6, 5, 4, 3],
       [4, 5, 6, 7, 8, 7, 6, 5, 4],
       [3, 4, 5, 6, 7, 6, 5, 4, 3],
       [2, 3, 4, 5, 6, 5, 4, 3, 2],
       [1, 2, 3, 4, 5, 4, 3, 2, 1],
       [0, 1, 2, 3, 4, 3, 2, 1, 0]])
# à vous de jouer

def stairs(n):
    pass
# pour vérifier
stairs(4)

https://nbhosting.inria.fr/auditor/notebook/python-mooc:exos/w7/w7-s05-x3-stairs

calculs imbriqués (avancé)

Regardez le code suivant :

# une fonction vectorisée
def pipeline(array):
    array2a = np.sin(array)
    array2b = np.cos(array)
    array3 = np.exp(array2a + array2b)
    array4 = np.log(array3+1)
    return array4

Les questions : j’ai un tableau X typé float64 et de forme (1000,)

indice