broadcasting / dimensions#

import numpy as np

on va commencer par quelques rappels et astuces

broadcasting#

un trait qui sera abordé en cours, mais qu’on peut mettre en évidence facilement

# un tableau en ligne
row = np.array([0, 1000, 2000, 3000])
# un tableau en colonne
col = np.array([[0], [10], [20]])
row
array([   0, 1000, 2000, 3000])
col
array([[ 0],
       [10],
       [20]])

eh bien ces deux tableaux, bien que n’ayant pas la même forme, peuvent s’ajouter !

row + col
array([[   0, 1000, 2000, 3000],
       [  10, 1010, 2010, 3010],
       [  20, 1020, 2020, 3020]])

reshaping#

pour fabriquer le tableau col ci dessus, on aurait pu procéder de plein d’autres façons

# en partant des données 'à plat'
raw = np.array([0, 10, 20])
# on aurait pu produire la forme de `col` comme ceci
# dans un reshape, le -1 est calculé pour boucher le trou
col1 = raw.reshape((-1, 1))
col1
array([[ 0],
       [10],
       [20]])
# avec newaxis
col2 = raw[:, np.newaxis]
col2
array([[ 0],
       [10],
       [20]])

indices#

la fonction np.indices est très pratique pour obtenir les rangs dans le tableau

# par exemple
I, J = np.indices((3, 4))
I, J
(array([[0, 0, 0, 0],
        [1, 1, 1, 1],
        [2, 2, 2, 2]]),
 array([[0, 1, 2, 3],
        [0, 1, 2, 3],
        [0, 1, 2, 3]]))

exercices#

Voici maintenant de quoi mettre ces astuces en pratique

table de multiplication#

Produisez le tableau de la table de multiplication des entiers entre 1 et n

On peut le faire de au moins 3 façons (cf les 3 premières sections ci-dessus)

N = 5

# à vous

échiquier#

base - v1#

On veut écrire une fonction qui produit un échiquier

ex. avec checkers(3, 4)

0

1

0

1

1

0

1

0

0

1

0

1

# à vous

def checkers():
    """
    vous avez le droit d'écrire le docstring :)
    """
    ...
# ceci doit afficher True

np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

Hide code cell output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[13], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

TypeError: checkers() takes 0 positional arguments but 2 were given

v2 - pareil, mais doit retourner des booléens#

# à vous

def checkers():
    ...
# ceci doit afficher True

np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

Hide code cell output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[15], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

TypeError: checkers() takes 0 positional arguments but 2 were given
# ceci doit afficher True

checkers(3, 4).dtype == bool

Hide code cell output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[16], line 3
      1 # ceci doit afficher True
----> 3 checkers(3, 4).dtype == bool

TypeError: checkers() takes 0 positional arguments but 2 were given

affichage#

comment feriez-vous pour afficher le tableau comme un damier ?

[indice] voyez plt.imshow()

# à vous
...

paramètrer le coin#

Pour corser un peu, on ajoute un paramètre optionnel qui indique, lorsqu’il est True, qu’on veut que l’échiquer est inversé

ex. avec checkers(3, 4, True)

1

0

1

0

0

1

0

1

1

0

1

0

mais les appels avec seulement deux paramètres continuent à fonctionner comme avant

# à vous
# ceci doit afficher True

np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

Hide code cell output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[19], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

TypeError: checkers() takes 0 positional arguments but 2 were given
# ceci doit afficher True

np.all(checkers(3, 4, True) == ~(checkers(3, 4)))

Hide code cell output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[20], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4, True) == ~(checkers(3, 4)))

TypeError: checkers() takes 0 positional arguments but 3 were given
# pour débugger
checkers(3, 4)

Hide code cell output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[21], line 2
      1 # pour débugger
----> 2 checkers(3, 4)

TypeError: checkers() takes 0 positional arguments but 2 were given
# pour débugger
checkers(3, 4, True)

Hide code cell output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[22], line 2
      1 # pour débugger
----> 2 checkers(3, 4, True)

TypeError: checkers() takes 0 positional arguments but 3 were given

tester#

On veut maintenant tester que si on ajoute ces deux formes on n’obtient que des 1

# à vous d'écrire le code qui vous permettra de vous en assurer

escaliers#

écrivez une fonction qui retourne une espèce de pyramide escalier comme ceci

si le paramètre est 2, on retourne un tableau de taille \(2*n+1\)

stairs(2)

0

1

2

1

0

1

2

3

2

1

2

3

4

3

2

1

2

3

2

1

0

1

2

1

0

quelques indices#

toujours pour le cas où n=2, voici quelques phrases que je vous laisse lire

I, J = np.indices((5, 5))
# si on décale, retourne, et applique abs()
abs(2-I), abs(2-J)
(array([[2, 2, 2, 2, 2],
        [1, 1, 1, 1, 1],
        [0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2]]),
 array([[2, 1, 0, 1, 2],
        [2, 1, 0, 1, 2],
        [2, 1, 0, 1, 2],
        [2, 1, 0, 1, 2],
        [2, 1, 0, 1, 2]]))
# si on les ajoute
abs(2-I) + abs(2-J)
array([[4, 3, 2, 3, 4],
       [3, 2, 1, 2, 3],
       [2, 1, 0, 1, 2],
       [3, 2, 1, 2, 3],
       [4, 3, 2, 3, 4]])
# on y est presque
4-(abs(2-I) + abs(2-J))
array([[0, 1, 2, 1, 0],
       [1, 2, 3, 2, 1],
       [2, 3, 4, 3, 2],
       [1, 2, 3, 2, 1],
       [0, 1, 2, 1, 0]])
# à vous de mettre tout cela ensemble

def stairs(n):
    ...
# comment feriez-vous pour afficher le résultat visuellement ?

# à vous