Main

Retour vers le tutoriel complet

Gestion des entrées/sorties, déclaration des variables

Les variables sont créées automatiquement lors de leur déclaration. Le type des variables est déterminé automatiquement.

Création de variables, les approches classiques

Taper les lignes de code suivantes et visualiser les résultats.

NB : le code sera tapé dans un fichier puis le fichier sera exécuté, la console ne servira qu'à visualiser le résultat.

Création directe et à l'aide de fonctions dédiées

a = 2 # variable contenant la valeur 2
m0 = np.array([[1, 2], [3, 4]])     # matrice
                                    # matrice = vecteur de vecteurs
v1 = np.arange(0, 10, 1) # create a range
                         # arguments: start, stop, step
v1 = np.arange(0, 10)    # with default arg
v2 = np.linspace(0, 10, 15) # avec linspace, le début et la fin SONT inclus

m1 = np.ones((10,2))  # matrice de 1, argument = nuplet avec les dimensions
                      # ATTENTION np.ones(10,2) ne marche pas

m2 = np.zeros((5,4))   # matrice de 0
m3 = np.eye(4)        # matrice identité carrée, arg = dimension
m4 = np.random.rand(5,6)  # matrice de nombres aléatoires indépendants, args = dimensions
m5 = np.random.randn(5,6) # tirages selon une gaussienne(mu=0,var=1), args = dimensions

m6 = m5.T          # pour la transposée
m5.transpose();    # ou bien
np.transpose(m5);  # ou bien
# la plupart des fonctions numpy acceptent la syntaxe objet et la syntaxe non-objet.

Concaténation de matrices

hstack et vstack

m6 = np.vstack((np.array([[1, 2], [3, 4]]), np.ones((3,2))))
m7 = np.vstack((np.array([1, 2, 3]), np.hstack((np.ones((3,2)), np.zeros((3,1))))))

Astuce pour créer des matrices d'un autre type:

# une matrice d'entier
matInt   = np.zeros((5,6), int) # matrice 5x6 de 0 (entiers)
matBool  = np.zeros((5,6), bool) # matrice 5x6 de False (booléens)
matBool2 = np.ones((5,6), bool) # matrice 5x6 de True (booléens)

Affichage console

Pour afficher une variable v:

print(v1) # parenthèses obligatoires en python 3

Pour afficher un message formaté:

print("{} : {}".format("la valeur est ", m5[0][0]))

Pour toutes les règles de formatage avancé : lien
Ne pas tester en TME {$\Rightarrow$} à la maison

Affectation/récupération de valeurs

Récupération de valeurs

# une matrice
mat   = np.ones((5,6))
mat[0,0] # récupération de la première valeur
mat[0,:] # récupération de la première ligne
mat[0,0:2] # récupération des valeurs d'indice 0 et 1
# petites astuces supplémentaires
mat[0,1:] # toute la ligne sauf la première case
mat[0,:-1] # toute la ligne sauf la dernière case
mat[0,:-2] # toute la ligne sauf les deux dernières cases

A = np.array([1,2,3,4,5])
A[1:3]  # array([2, 3])

# On peut omettre n'importe lequel des argument dans M[start:stop:step]:
A[::] # indices de début, fin, et pas avec leurs valeurs par défaut
      # array([ 1, -2, -3,  4,  5])
A[::2] # pas = 2, indices de début et de fin par défaut
       # array([ 1, -3,  5])
A[:3] # les trois premiers éléments (indices 0,1,2)
      # array([ 1, -2, -3])
A[3:] # à partir de l'indice 3
      # array([4, 5])

# On peut utiliser des indices négatifs :
A[-1] # le dernier élément
      # 5
A[-3:] # les 3 derniers éléments
       # array([3, 4, 5])

Affectation sur le même principe:

# une matrice d'entier
mat   = np.ones((5,6))
mat[0,0:2] = 1 # affectation en bloc
mat[0,0:2] = np.zeros((1,2)) # affectation en bloc d'une autre matrice

Etat de la mémoire

Pour faire le bilan des variables existant dans l'environnement actuel:

 whos # ne marche que sous ipython
whos # pour voir toutes les variables, leurs types et leurs tailles

# pour une variable:
notes.shape # (15,2)
notes.shape[0] # 15
notes.shape[1] # 2
n, m = notes.shape # retours multiples

Types de base vs objets

Comme dans tous les langages, il faut faire attention aux copies de surface:

m = np.array([[1, 2], [3, 4]])
m2 = m           # shallow copy (évidemment)
m2[0][0] = 5
print(m)
# Affichage
# [[5 2]
#  [3 4]]

m3 = m.copy()      # deep copy
m3[0][1] = 6
print(m)
# Affichage => m inchangée
# [[5 2]
#  [3 4]]

Chargement/sauvegarde de matrices de valeurs

Syntaxe simple et intuitive (+formattage optionnel proche du C/JAVA):

np.savetxt("random-matrix.txt", m5)
# donne le fichier:
# 1.000000000000000000e+00 2.000000000000000000e+00
# 3.000000000000000000e+00 4.000000000000000000e+00
np.savetxt("random-matrix.csv", m5, fmt='%.5f', delimiter=',')
# donne le fichier:
# 1.00000,2.00000
# 3.00000,4.00000

loadtxt/savetxt: idéal pour MAPSI...

  • Chargement/sauvegarde des matrices, format lisible de l'extérieur si besoin
  • Echanges possibles avec d'autres langages: matlab, JAVA...

... Mais pour le python, on préfère souvent pickle

  • Serialization généralisé: pour les valeurs, les objets (dont les matrices), les listes, les dictionnaires...
  • Très facile à utiliser
  • Utilisé par tout le monde en python... Donc à connaitre

Fonctionnement:

import pickle as pkl     # obligatoire pour pouvoir l'utiliser
# chargement de données
data = pkl.load(open('ressources/usps_small.pkl','rb')) # attention à donner un file + option lecture (pas juste un nom de fichier)
# sauvegarde d'un dictionnaire
pkl.dump({"letters":letters, "labels":labs}, file("ressources/lettres.pkl","wb"))

Exercices de synthèse

Génération de données

Nous souhaitons créer une matrice 10x3 dont la première colonne contient les indices 1 à 10 dans l'ordre. La seconde colonne contiendra des nombres aléatoires entre 0 et 1. La troisième colonne ne contiendra que des 0.

Vous ajouterez ensuite une ligne en haut de la matrice contenant les indices de colonne 1 à 3.

NB: vous pouvez créer des matrices dans des matrices, c'est-à-dire faire appel à des fonctions dans les [].

Exemple de résultat possible:

    1.00000    2.00000    3.00000
    1.00000    0.03479    0.00000
    2.00000    0.66074    0.00000
    3.00000    0.15187    0.00000
    4.00000    0.03640    0.00000
    5.00000    0.62497    0.00000
    6.00000    0.54774    0.00000
    7.00000    0.68919    0.00000
    8.00000    0.86146    0.00000
    9.00000    0.72030    0.00000
   10.00000    0.84590    0.00000

Sauvegarde/chargement de données

Saisir dans un fichier texte college.dat les deux colonnes de nombres suivantes (vous utiliserez TextEdit, nedit, gedit, emacs ...). Ces nombres correspondent à des notes (2 épreuves) d'élèves (15) sur lesquelles nous travaillerons par la suite.

 14.5  8.5 
 15.5  8.5
 9     14.5
 9.5   15.5
 11    9.5 
 3.5   6
 11.5  11
 8.5   5.5
 3     2
 17    12
 6     13
 10    12.5
 10    4
 11.5  5.5
 13.5  8

Chargement du fichier en utilisant la fonction symétrique de la fonction de sauvegarde:

notes = np.loadtxt('college.dat')

Après avoie recharger "ressources/lettres.pkl" dans une variable result, on accède aux champs en faisant:

  • result.letters et result.labs