import numpy as np
np.__version__
'1.16.2'
import matplotlib.pyplot as plt
np.set_printoptions(precision=2) # pour fixer le nombre de digits affichés
# un vecteur: l'argument de la fonction est une liste Python
liste = [1, 3, 2, 4]
vecteur = np.array(liste)
print(vecteur)
[1 3 2 4]
# 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])
[[1 2] [3 4]] 1 2
tenseur = np.array([[[1, 2], [3, 4]],
[[21, 21], [23, 34]]])
print(tenseur)
[[[ 1 2] [ 3 4]] [[21 21] [23 34]]]
type(vecteur), type(matrice), type(tenseur)
(numpy.ndarray, numpy.ndarray, numpy.ndarray)
np.shape(vecteur), matrice.shape, tenseur.shape
((4,), (2, 2), (2, 2, 2))
matrice_cpx = np.array([[1, 2], [3, 4]], dtype=complex)
matrice_cpx
array([[1.+0.j, 2.+0.j], [3.+0.j, 4.+0.j]])
x = np.arange(0, 10, 2) # arguments: start, stop, step
x
array([0, 2, 4, 6, 8])
y = np.arange(-1, 1, 0.5)
y
array([-1. , -0.5, 0. , 0.5])
print(x.dtype, y.dtype)
int64 float64
linspace:
# avec linspace, le début et la fin SONT inclus
np.linspace(0, 5, 11)
array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ])
logspace:
np.logspace(0, 11, 10)
array([1.00e+00, 1.67e+01, 2.78e+02, 4.64e+03, 7.74e+04, 1.29e+06, 2.15e+07, 3.59e+08, 5.99e+09, 1.00e+11])
10**(np.linspace(np.log10(1), np.log10(10**11), 10))
array([1.00e+00, 1.67e+01, 2.78e+02, 4.64e+03, 7.74e+04, 1.29e+06, 2.15e+07, 3.59e+08, 5.99e+09, 1.00e+11])
diag : première utilisation
np.diag([1, 2, 3], k=0)
array([[1, 0, 0], [0, 2, 0], [0, 0, 3]])
np.diag([1, 2, 3], k=1)
array([[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3], [0, 0, 0, 0]])
np.diag([1, 2, 3], k=1).T
array([[0, 0, 0, 0], [1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0]])
np.transpose(np.diag([1, 2, 3], k=1))
array([[0, 0, 0, 0], [1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0]])
diag : seconde utilisation
np.diag(np.diag([1, 2, 3], k=0))
array([1, 2, 3])
zeros
np.zeros((3,), dtype=int)
array([0, 0, 0])
print(np.zeros((3, 2), dtype=float))
print(np.zeros((1, 3), dtype=float))
print(np.zeros((3, 1), dtype=float))
[[0. 0.] [0. 0.] [0. 0.]] [[0. 0. 0.]] [[0.] [0.] [0.]]
ones
np.ones((3,3))
array([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])
full
np.full((3, 5), 3.14)
array([[3.14, 3.14, 3.14, 3.14, 3.14], [3.14, 3.14, 3.14, 3.14, 3.14], [3.14, 3.14, 3.14, 3.14, 3.14]])
eye
np.eye(3)
array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
np.eye(3, dtype=int)
array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
A = np.array([[0, 2],[ 3, 4]])
B = np.array([[1, 2],[ 5, 4]])
np.vstack((A,B)) # concaténation verticale
array([[0, 2], [3, 4], [1, 2], [5, 4]])
np.hstack((A,B)) # concaténation horizontale
array([[0, 2, 1, 2], [3, 4, 5, 4]])
mean (en français 'moyenne')
np.mean(A)
2.25
np.mean(B,axis=0) # moyenne des colonnes
array([3., 3.])
np.mean(B,axis=1) # moyenne des lignes
array([1.5, 4.5])
sum (en français 'somme')
np.sum(A)
9
np.sum(A, axis=0) # somme en colonne
array([3, 6])
np.sum(A, axis=1) # somme en ligne
array([2, 7])
cumsum (en français 'sommes cumulées')
np.cumsum(A) # noter l'ordre en ligne
array([0, 2, 5, 9])
np.cumsum(A, axis=0) # somme cumulée en colonne
array([[0, 2], [3, 6]])
np.cumsum(A, axis=1) # somme cumulée en ligne
array([[0, 2], [3, 7]])
Note: il existe la même chose avec prod et cumprod pour le produit au lieu de l'addition.
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:
A[:, 0] # accès à la première colonne
array([0, 3])
A[1, :] # accès à la deuxième ligne
array([3, 4])
Il est aussi utile de travailler avec des masques:
print(A < 2)
print(A[A < 2])
A[A < 2]= 0.
print(A) # met à zéro tous les termes plus petit que 2
[[ True False] [False False]] [0] [[0 2] [3 4]]
2**A
array([[ 1, 4], [ 8, 16]])
A**3
array([[ 0, 8], [27, 64]])
A + 1
array([[1, 3], [4, 5]])
np.exp(A)
array([[ 1. , 7.39], [20.09, 54.6 ]])
from scipy.linalg import expm
expm(A)
array([[ 32.33, 55.1 ], [ 82.65, 142.54]])
A @ B
array([[10, 8], [23, 22]])
A.dot(B)
array([[10, 8], [23, 22]])
np.dot(A, B)
array([[10, 8], [23, 22]])
np.random.rand(5, 5) # nombres aléatoire entre 0. et 1.
array([[0.74, 0.81, 0.52, 0.39, 0.78], [0.25, 0.09, 0.93, 0.5 , 0.4 ], [0.5 , 0.14, 0.93, 0.08, 0.73], [0.83, 0.87, 0.72, 0.74, 0.16], [0.37, 0.72, 0.31, 0.91, 0.29]])
np.random.rand(5, ) # un deuxième tirage
array([0.76, 0.77, 0.05, 0.65, 0.34])
np.random.seed(2018)
np.random.rand(5, ) # un premier tirage aléatoire
array([0.88, 0.1 , 0.91, 0.31, 0.45])
np.random.seed(2018)
np.random.rand(5, ) # un tirage identique.
array([0.88, 0.1 , 0.91, 0.31, 0.45])
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")
from download import download
# pip install download # si besoin, décommenter et exécuter cette cellule.
pwd # unix command "print working directory"
'/home/jo/Documents/Mes_cours/Montpellier/HLMA310/Poly/codes'
url = "http://josephsalmon.eu/enseignement/datasets/data_test.csv"
path_target = "./data_set.csv"
download(url, path_target, replace=False)
file_sizes: 100%|████████████████████████████| 30.0/30.0 [00:00<00:00, 16.2kB/s]
Downloading data from http://josephsalmon.eu/enseignement/datasets/data_test.csv (30 bytes) Successfully downloaded file to ./data_set.csv
'./data_set.csv'
!cat data_set.csv # permet de lancer la commande unix cat pour visualiser le fichier
1,2,3,4,5 6,7,8,9,10 1,3,3,4,6
!cat data_set.csv # dans un notebook la commande cat fonctionne aussi
1,2,3,4,5 6,7,8,9,10 1,3,3,4,6
Note: d'autres fonctions unix sont disponibles en plus de pwd et cat:
data_as_array = np.genfromtxt('data_set.csv', delimiter=',')
data_as_array
array([[ 1., 2., 3., 4., 5.], [ 6., 7., 8., 9., 10.], [ 1., 3., 3., 4., 6.]])
np.savetxt("random_matrix.txt", data_as_array)
!cat random_matrix.txt
1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00 4.000000000000000000e+00 5.000000000000000000e+00 6.000000000000000000e+00 7.000000000000000000e+00 8.000000000000000000e+00 9.000000000000000000e+00 1.000000000000000000e+01 1.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 4.000000000000000000e+00 6.000000000000000000e+00
Le format le plus courant pour sauvegarder un array est le format 'npy':
np.save("random_matrix.npy", data_as_array)
Pour charger un tel fichier il suffit alors de faire:
data_as_array2 = np.load("random_matrix.npy")
data_as_array2
array([[ 1., 2., 3., 4., 5.], [ 6., 7., 8., 9., 10.], [ 1., 3., 3., 4., 6.]])
!rm data_set.csv
!rm random_matrix.txt
!rm random_matrix.npy
Note: la fonction rm vient de l'anglais remove (en français 'supprimer')
Pour des raisons de performance Python ne copie pas automatiquement les objets (par exemple passage par référence des paramètres de fonctions).
A = np.array([[0, 2],[ 3, 4]])
B = A
Changer B va maintenant affecter A
B[0,0] = 10
B
array([[10, 2], [ 3, 4]])
print(A)
print(B is A) # les deux objets sont les mêmes
[[10 2] [ 3 4]] True
Pour éviter ce comportement, on peut demander une copie profonde (deep copy en anglais) de A dans B:
B = A.copy()
B[0,0] = 111
B
array([[111, 2], [ 3, 4]])
A # A n'est alors plus modifié car on a créé une copie de l'objet!
array([[10, 2], [ 3, 4]])
A == B
array([[False, True], [ True, True]])
np.allclose(A,A+0.001)
False
np.allclose(A,A+0.001, atol=0.01)
True