import numpy as np
Regardons comment extraire des morceaux d'un tableau ou modifier seulement certaines de ses parties. Pour cela nous disposons de deux outils :
On peut extraire des valeurs d'un tableau en fonction de ses indices comme on l'a fait pour les listes. Pour chaque dimension du tableau on peut indiquer
debut:fin:saut
. Ainsi 1:6:2
veut dire les valeurs impaires entre l'indice 1 et l'indice 6 exclus. Les valeurs debut
, fin
et saut
sont optionnelles ::5
donne les 5 première valeurs (indices 0,1,2,3 et 4)3:
donne de la 4-ième à la dernière valeurs::3
donne une valeur sur 3 du début à la fin du tableau.[1,3,-2]
(les valeurs négatives commencent par la fin, -2
est l'avant dernier indice)a = np.arange(12).reshape(3,4)
print(a, '\n')
print(a[1, :], '\n') # 2nd line
print(a[0:2, 0:2], '\n') # top left sub-matrix
print(a[::2, -1], '\n') # even lines, last column
print(a[:, [0,-1]]) # first and last column
[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [4 5 6 7] [[0 1] [4 5]] [ 3 11] [[ 0 3] [ 4 7] [ 8 11]]
Il est ainsi possible d'indiquer qu'une opération ne s'applique qu'à un extrait du tableau en indiquant quelles sont les cases du tableau qui seront modifiées :
a[::2, 1::2] += 100
a
array([[ 0, 101, 2, 103], [ 4, 5, 6, 7], [ 8, 109, 10, 111]])
Cela permet aussi d'écrire simplement des calculs comme extraire une image en niveau de gris d'une image en couleur :
image = np.random.randint(256, size=(800, 600, 3)) # RGB 800x600 image
gray_image = 0.2126 * image[:,:,0] + 0.7152 * image[:,:,1] + 0.0722 * image[:,:,2]
On peut aussi utiliser ...
pour remplacer plusieurs indices ainsi image[...,0] == image[:,:,0]
Numpy permet d'extraire simplement les valeurs qui répondent à une condition logique.
Pour cela on utilise un filtre, à savoir un tableau booléen que l'on pose sur un tableau de même dimension en imaginant que les cases True sont des fenêtres et False des murs. Le résultat est l'ensemble des valeurs qu'on voit à travers les fenêtres ordonnées par leur indice.
Le résultat est toujours un tableau en 1 dimension sauf si on utilise where
.
a = np.arange(12).reshape(3,4)
fil = a > 5 # a > 5 means all VALUES greater than 5
print("The filter a > 5 is\n", fil)
a[fil] # apply the filter and show the result (1D array)
The filter a > 5 is [[False False False False] [False False True True] [ True True True True]]
array([ 6, 7, 8, 9, 10, 11])
Il est bien plus simple et lisible d'écrire la condition logique là où on met normalement les indices, à savoir entre les crochets :
a[a>5]
array([ 6, 7, 8, 9, 10, 11])
Le filtre peut servir à autre chose qu'a séléctionner les valeurs de notre tableau. Il peut être le résultat sur lequel on veut travailler, par exemple pour une population fil = (age == weight)
. C'est un tableau de booléen qui donne des cas vrai et d'autre faux c.a.d. des 0 et des 1.
Ainsi, avec un filtre fil
, on peut savoir
combien de cas sont vrai : | fil.sum() |
|
s'il y a au moins un cas vrai : | fil.sum() > 0 |
Numpy offre aussi np.any(fil) |
si tous les cas sont vrai : | fil.prod() == 1 |
Numpy offre aussi np.all(fil) |
si au moins un cas est faux : | fil.prod() == 0 |
|
si tous les cas sont faux : | fil.sum() == 0 |
np.where(a > 5, a, 0) # if a > 5 then a else 0
array([[ 0, 0, 0, 0], [ 0, 0, 6, 7], [ 8, 9, 10, 11]])
On peut faire tous les filtres imaginables qui donnent un tableau de booléan.
np.where(a%3 == 0, 2*a, -1) # if a modulo 3 is 0 then 2 times a else -1
array([[ 0, -1, -1, 6], [-1, -1, 12, -1], [-1, 18, -1, -1]])
Une autre facon de conserver la forme du tableau consiste à ne modifier que les valeurs qui correspondent au filtre.
a = np.arange(12).reshape(3,4)
a[a > 5] = 200
a
array([[ 0, 1, 2, 3], [ 4, 5, 200, 200], [200, 200, 200, 200]])
Voici comment ajouter 100 à toutes les valeurs du tableau qui sont des carrés parfait ainsi qu'à la valeur 5 :
a = np.arange(12).reshape(3,4)
a[(np.round(np.sqrt(a)) - np.sqrt(a) == 0) | (a==5)] += 100 # | is OR (AND is &)
a
array([[100, 101, 2, 3], [104, 105, 6, 7], [ 8, 109, 10, 11]])
{{ PreviousNext("np01 Numpy Introduction.ipynb", "np03 Manipulations.ipynb")}}