#!/usr/bin/env python # coding: utf-8 # # Premiers pas en *numpy* # # *** # > __Auteur__: Joseph Salmon # > # In[1]: import numpy as np np.__version__ # In[2]: import matplotlib.pyplot as plt # In[3]: np.set_printoptions(precision=2) # pour fixer le nombre de digits affichés # ## Génération d'arrays à partir de listes # In[4]: # un vecteur: l'argument de la fonction est une liste Python liste = [1, 3, 2, 4] vecteur = np.array(liste) print(vecteur) # In[5]: # une matrice: l'argument est une liste emboitée matrice = np.array([[1, 2], [3, 4]]) print(matrice) print(matrice[0,0]) print(matrice[0,1]) # In[6]: tenseur = np.array([[[1, 2], [3, 4]], [[21, 21], [23, 34]]]) print(tenseur) # In[7]: type(vecteur), type(matrice), type(tenseur) # In[8]: np.shape(vecteur), matrice.shape, tenseur.shape # In[9]: matrice_cpx = np.array([[1, 2], [3, 4]], dtype=complex) matrice_cpx # ## Génération d'arrays à partir de fonctions # In[10]: x = np.arange(0, 10, 2) # arguments: start, stop, step x # In[11]: y = np.arange(-1, 1, 0.5) y # In[12]: print(x.dtype, y.dtype) # **linspace**: # In[13]: # avec linspace, le début et la fin SONT inclus np.linspace(0, 5, 11) # **logspace**: # In[14]: np.logspace(0, 11, 10) # In[15]: 10**(np.linspace(np.log10(1), np.log10(10**11), 10)) # **diag** : première utilisation # In[16]: np.diag([1, 2, 3], k=0) # In[17]: np.diag([1, 2, 3], k=1) # In[18]: np.diag([1, 2, 3], k=1).T # In[19]: np.transpose(np.diag([1, 2, 3], k=1)) # **diag** : seconde utilisation # In[20]: np.diag(np.diag([1, 2, 3], k=0)) # **zeros** # In[21]: np.zeros((3,), dtype=int) # In[22]: print(np.zeros((3, 2), dtype=float)) print(np.zeros((1, 3), dtype=float)) print(np.zeros((3, 1), dtype=float)) # **ones** # In[23]: np.ones((3,3)) # **full** # In[24]: np.full((3, 5), 3.14) # **eye** # In[25]: np.eye(3) # In[26]: np.eye(3, dtype=int) # ## Concaténation d'array # In[27]: A = np.array([[0, 2],[ 3, 4]]) B = np.array([[1, 2],[ 5, 4]]) np.vstack((A,B)) # concaténation verticale # In[28]: np.hstack((A,B)) # concaténation horizontale # ## Fonctions sur les lignes / colonnes: # **mean** (en français 'moyenne') # In[29]: np.mean(A) # In[30]: np.mean(B,axis=0) # moyenne des colonnes # In[31]: np.mean(B,axis=1) # moyenne des lignes # **sum** (en français 'somme') # In[32]: np.sum(A) # In[33]: np.sum(A, axis=0) # somme en colonne # In[34]: np.sum(A, axis=1) # somme en ligne # **cumsum** (en français 'sommes cumulées') # In[35]: np.cumsum(A) # noter l'ordre en ligne # In[36]: np.cumsum(A, axis=0) # somme cumulée en colonne # In[37]: np.cumsum(A, axis=1) # somme cumulée en ligne # Note: il existe la même chose avec **prod** et **cumprod** pour le produit au lieu de l'addition. # ## Slicing # Comme pour les string que l'on a déjà vu, le slicing est disponible pour les arrays, avec en plus la possibilité d'y avoir accès pour chaque dimension: # In[38]: A[:, 0] # accès à la première colonne # In[39]: A[1, :] # accès à la deuxième ligne # Il est aussi utile de travailler avec des masques: # In[40]: print(A < 2) print(A[A < 2]) A[A < 2]= 0. print(A) # met à zéro tous les termes plus petit que 2 # ## Vectorisation des operations # In[41]: 2**A # In[42]: A**3 # In[43]: A + 1 # In[44]: np.exp(A) # In[45]: from scipy.linalg import expm expm(A) # ## Mutliplication matricielle: # In[46]: A @ B # In[47]: A.dot(B) # In[48]: np.dot(A, B) # ## Génération aléatoire # ### rand : la loi uniforme sur $[0,1]$ # In[49]: np.random.rand(5, 5) # nombres aléatoire entre 0. et 1. # In[50]: np.random.rand(5, ) # un deuxième tirage # In[51]: np.random.seed(2018) np.random.rand(5, ) # un premier tirage aléatoire # In[52]: np.random.seed(2018) np.random.rand(5, ) # un tirage identique. # ### randn : la loi normale/gaussienne: # In[53]: from scipy.stats import norm # module loi normale a = np.random.randn(10000) x = np.linspace(-4, 4, 100) # Affichage d'un histogramme normalisé avec matplotlib fig = plt.figure(figsize=(8, 5)) hitogramme = plt.hist(a, bins=50, density=True) # Oublier les détails matplotlib et Latex dans un premier temps plt.plot(x, norm.pdf(x), linewidth=3, color='black', label=r"$\frac{1}{\sqrt{2\pi}} \cdot \exp\left(-\frac{x^2}{2}\right)$") plt.xlabel("x") plt.ylabel("Proportion") plt.legend() plt.show() saving = False if saving is True: fig.savefig("../prebuiltimages/gaussian.pdf") # ## Génération par importation de données # In[54]: from download import download # In[55]: # pip install download # si besoin, décommenter et exécuter cette cellule. # In[56]: pwd # unix command "print working directory" # In[57]: url = "http://josephsalmon.eu/enseignement/datasets/data_test.csv" path_target = "./data_set.csv" download(url, path_target, replace=False) # In[58]: get_ipython().system('cat data_set.csv # permet de lancer la commande unix cat pour visualiser le fichier') # In[59]: get_ipython().system('cat data_set.csv # dans un notebook la commande cat fonctionne aussi') # Note: d'autres fonctions unix sont disponibles en plus de **pwd** et **cat**: # - **cd** : pour changer de dossier (* **c**hange **d**irectory* en anglais) # - **cp** : pour copy des fichiers (* **c**o**p**y* en anglais) # - **ls** : pour lister les fichiers à l'endroit courant (* **l**i**s**t* en anglais) # - **man** : pour avoir accès au manuel/aide (* **man**ual* en anglais) # - **mkdir** : pour créer un dossier (* **m**a**k**e **dir**ectory* en anglais) # - **mv** : pour déplacer un fichier (* **m**o**v**e* en anglais) # - **rm** : pour supprimer un fichier (* **r**e**m**ove* en anglais) # - **rmdir** : pour supprimer un dossier (* **r**e**m**ove **dir**ectory* en anglais) # - etc. # In[60]: data_as_array = np.genfromtxt('data_set.csv', delimiter=',') data_as_array # ## Export sous divers formats: # In[61]: np.savetxt("random_matrix.txt", data_as_array) # In[62]: get_ipython().system('cat random_matrix.txt') # Le format le plus courant pour sauvegarder un array est le format 'npy': # In[63]: np.save("random_matrix.npy", data_as_array) # Pour charger un tel fichier il suffit alors de faire: # In[64]: data_as_array2 = np.load("random_matrix.npy") data_as_array2 # In[ ]: # ## Effacer le fichier après usage si l'on ne s'en sert plus: # In[65]: get_ipython().system('rm data_set.csv') get_ipython().system('rm random_matrix.txt') get_ipython().system('rm random_matrix.npy') # Note: la fonction **rm** vient de l'anglais *remove* (en français 'supprimer') # ## Copie / copie profonde (*deep copy*) # # Pour des raisons de performance Python ne copie pas automatiquement les objets (par exemple passage par référence des paramètres de fonctions). # In[66]: A = np.array([[0, 2],[ 3, 4]]) B = A # Changer B va maintenant affecter A # In[67]: B[0,0] = 10 B # In[68]: print(A) print(B is A) # les deux objets sont les mêmes # Pour éviter ce comportement, on peut demander une copie profonde (*deep copy* en anglais) de A dans B: # In[69]: B = A.copy() # In[70]: B[0,0] = 111 B # In[71]: A # A n'est alors plus modifié car on a créé une copie de l'objet! # ### Tests entre arrays # In[72]: A == B # In[73]: np.allclose(A,A+0.001) # In[74]: np.allclose(A,A+0.001, atol=0.01) # In[ ]: