NumPy
fournit les types de données de base pour la data-science, les statistiques et l'analyse numérique : tableaux et matrices. La différence entre ces deux types de données est la suivante:
Les opérations arithmétiques sur les tableaux se font élément-par-élément. Le cas des matrices fait exception où la multiplication *
suit les règles de l'algèbre linéaire. Les tableaux de dimension 2 peuvent être multipliés suivants les règles de l'algèbre linéaire en utilisant la fonction dot
, et si on utilise Python 3.5 (ou plus), les tableaux peuvent être multipliés à l'aide du symbole @
. De manière similaire, la fonction multiply
peut être utilisée pour multiplier deux matrices élément-par-élément.
Les tableaux sont plus courants que les matrices et toutes les fonctions sont minutieusement testées sur les tableaux. Les mêmes fonctions devraient également fonctionner avec les matrices, mais un bug rare lors de l'utilisation des matrices n'est pas écarté.
asmatrix
ou mat
sans copier les données sous-jacentes.Les meilleures pratiques consistent à utiliser le format tableau en utilisant le symbole @
pour la multiplication matricielle. La fonction asmatrix
peut être utilisée lors l'écriture de code d'algèbre linéaire.
Les tableaux constituent le type de données de base dans la librairie NumPy. Ils sont similaires aux listes ou aux tuples car ils contiennent tous les deux des collections d'éléments. Cette section est axée sur les tableaux de données numériques, c’est-à-dire un tableau où tous les éléments ont le même type numérique. De plus, les tableaux, contrairement aux listes, sont toujours rectangulaires, de sorte que toutes les dimensions ont le même nombre d'éléments.
import numpy
x = [0.0, 1, 2, 3, 4]
y = array(x)
y
array([ 0., 1., 2., 3., 4.])
type(y)
numpy.ndarray
Des tableaux à deux dimensions (ou plus) sont initialisés à l'aide de listes imbriquées.
y = array([[0.0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
print(y)
print(y.shape)
y = array([[[1,2],[3,4]],[[5,6],[7,8]]])
print(y)
print(y.shape)
Les tableaux homogènes peuvent contenir divers types de données numériques. Le type de données le plus courant est float64
(ou double), ce qui correspond au type de données flottant intégré à python (et double en C/C++). Par défaut, les appels à array
préservent le type d'entrée, si possible. Si une entrée contient tous les entiers, elle aura le type int32
(similaire au type de données int
). Si une entrée contient des entiers, des flottants ou un mélange des deux, le type de données du tableau sera float64
. Si l'entrée contient un mélange d'entiers, de flottants et de types complexes, le tableau sera initialisé pour contenir des données complexes.
>>> x = [0, 1, 2, 3, 4] # Integers
>>> y = array(x)
>>> y.dtype
dtype('int32')
>>> x = [0.0, 1, 2, 3, 4] # 0.0 is a float
>>> y = array(x)
>>> y.dtype
dtype('float64')
>>> x = [0.0 + 1j, 1, 2, 3, 4] # (0.0 + 1j) is a complex
>>> y = array(x)
>>> y
array([ 0.+1.j,
1.+0.j,
2.+0.j,
3.+0.j,
4.+0.j])
>>> y.dtype
dtype('complex128')
NumPy tente de trouver le type de données le plus petit pouvant représenter les données lors de la construction d'un tableau. Il est possible de forcer NumPy à sélectionner un type particulier en utilisant le mot clé argument dtype = type de données lors de l'initialisation du tableau.
>>> x = [0, 1, 2, 3, 4] # Integers
>>> y = array(x)
>>> y.dtype
dtype('int32')
>>> y = array(x, dtype='float64') # String dtype
>>> y.dtype
dtype('float64')
>>> y = array(x, dtype=float32) # NumPy type dtype
>>> y.dtype
dtype('float32')
Une matrice est un cas particulier de tableaux et se comportent de manière pratiquement identique. Les deux différences importantes sont:
Les matrices possèdes 2 dimensions
Les matrices sont compatibles avec les règles de calcul d'algèbre linéaire.
Les tableaux à 1 et 2 dimensions peuvent être copiés dans une matrice en appelant matrix
sur un array
. Les fonctions mat
ou asmatrix
sont des méthodes plus rapides pour contraindre un tableau à se comporter comme une matrice sans copier aucune donnée.
>>> x = [0.0, 1, 2, 3, 4] # Any float makes all float
>>> y = array(x)
>>> type(y)
numpy.ndarray
>>> y * y # Element-by-element
array([ 0., 1., 4., 9., 16.])
>>> z = asmatrix(x)
>>> type(z)
numpy.matrixlib.defmatrix.matrix
>>> z * z # Error
ValueError: matrices are not aligned
Un vecteur $$x = [1 \quad 2 \quad 3 \quad 4 \quad 5]$$
est déclaré comme un tableau en dimension 1 via
>>> x=array([1.0, 2.0, 3.0, 4.0, 5.0])
array([ 1., 2., 3., 4., 5.])
>>> ndim(x)
1
Si un tableau à 2 dimensions est nécessaire, on utilise une liste imbriquée.
>>> x=array([[1.0,2.0,3.0,4.0,5.0]])
array([[ 1., 2., 3., 4., 5.]])
>>> ndim(x)
2
Une matrice étant toujours bidimensionnelle, une liste imbriquée n'est pas nécessaire pour initialiser une matrice ligne.
>>> x=matrix([1.0,2.0,3.0,4.0,5.0])
>>> x
matrix([[ 1., 2., 3., 4., 5.]])
>>> ndim(x)
2
Pour entrer une matrice colonne, nous avons besoin d'une série de listes imbriquées comme suit
>>> x=matrix([[1.0],[2.0],[3.0],[4.0],[5.0]])
>>> x
matrix([[ 1.],
[ 2.],
[ 3.],
[ 4.],
[ 5.]])
>>> x = array([[1.0],[2.0],[3.0],[4.0],[5.0]])
>>> x
array([[ 1.],
[ 2.],
[ 3.],
[ 4.],
[ 5.]])
La déclaration d'une matrice ou d'un tableaux à 2 dimensions revient à entrer les lignes une par une dans une liste comme suit
>>> x = array([[1.0,2.0,3.0],[4.0,5.0,6.0],[7.0,8.0,9.0]])
>>> x
array([[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.]])
Les tableaux de dimensions supérieures ont de nombreuses utilisations, par exemple pour modéliser une covariance variant dans le temps.
Des tableaux multidimensionnels ($N$ dimensions) sont disponibles pour $N$ allant jusqu’à environ $30$, en fonction de la taille de chaque dimension marginale. Initialiser manuellement des tableaux multidimensionnels est fastidieux et sujet à erreur, il est donc préférable d’utiliser des fonctions telles que zeros((2, 2, 2))
ou empty((2, 2, 2))
.
import numpy as np
x = np.zeros((2,2,2))
print(x)
y = np.empty((2,2,2))
print(y)
La juxtaposition est le processus par lequel un vecteur ou une matrice est ajouté à un autre. Les tableaux et les matrices peuvent être concaténés horizontalement ou verticalement. Une juxtaposition se fait à l'aide de la fonction concatenate
. Les entrées de la fonction concatenate
doivent être regroupées dans un tuple et l’argument axis
indique si les tableaux doivent être juxtaposés verticalement (axe=0
) ou horizontalement (axe=1
).
>>> x = array([[1.0,2.0],[3.0,4.0]])
>>> y = array([[5.0,6.0],[7.0,8.0]])
>>> z = concatenate((x,y),axis = 0)
>>> z
array([[ 1., 2.],
[ 3., 4.],
[ 5., 6.],
[ 7., 8.]])
>>> z = concatenate((x,y),axis = 1)
>>> z
array([[ 1., 2., 5., 6.],
[ 3., 4., 7., 8.]])
L'opération de juxtaposition donne des résultats équivalent à une matrice définie par blocs (vocabulaire d'algèbre linéaire). De manière similaire, les fonctions vstack
et hstack
peuvent être utilisées pour juxtaposer des tableaux verticalement ou horizontalement.
>>> z = vstack((x,y)) # Similaire à z = concatenate((x,y),axis = 0)
>>> z = hstack((x,y)) # Similaire à z = concatenate((x,y),axis = 1)
Plusieurs méthodes sont possibles pour accéder aux éléments d'un tableau: la sélection scalaire, l'opération de slicing et l'indexation logique (ou booléenne). La sélection scalaire et le slicing sont les plus simples et sont donc présentés en premier.
La sélection scalaire est la méthode la plus simple pour sélectionner des éléments dans un tableau. Elle est implémentée en utilisant $[i]$ pour les tableaux à une dimension, $[i, j]$ pour les tableaux à deux dimensions et $[i_1, i_2, \ldots, i_n]$ pour les tableaux à $n$ dimensions. Comme pour toute indexation en Python, l'indexation part de $0$, de sorte que $[0]$ soit le premier élément d'un tableau à une dimension, $[0,0]$ soit l'élément supérieur gauche d'un tableau à 2 dimensions, etc.
>>> x = array([1.0,2.0,3.0,4.0,5.0])
>>> x[0]
1.0
>>> x = array([[1.0,2,3],[4,5,6]])
>>> x
array([[ 1., 2., 3.],
[ 4., 5., 6.]])
>>> x[1, 2]
6.0
>>> type(x[1,2])
numpy.float64
La sélection scalaire nous renvoie toujours un seul élément qui n'est pas un tableau. Le type de données de l'élément sélectionné correspond au type de données du tableau utilisé dans la sélection. La sélection scalaire peut également être utilisée pour affecter des valeurs dans un tableau.
>>> x = array([1.0,2.0,3.0,4.0,5.0])
>>> x[0] = -5
>>> x
array([-5., 2., 3., 4., 5.])
Les opérations de type slicing sur les tableaux sont pratiquement identiques aux listes. La syntaxe est données par [:,:,...,:]
où le nombre de dimensions détermine la taille de la coupe. Rappelons la notation de coupe a:b:s
sélectionnera chaque s
ème élément où les indices $i$ vérifient la conditions $a ≤ i <b$, de sorte que la valeur de départ $a$ soit toujours incluse dans la liste et que la valeur finale $b$ soit toujours exclue.
Les notations :
et ::
sont les mêmes que 0:n:1
où n
est la longueur d'un tableau (ou liste).
a:
et a:n
sont les mêmes que a:n:1
où n
est la longueur d'un tableau (ou liste).
:b
est la même que 0:b:1
::s
est la même que 0:n:s
où n
est la longueur d'un tableau (ou liste).
Il n'est pas nécessaire d'inclure toutes les dimensions de fin de coupe et les éventuelles coupes de fin omises sont configurées pour sélectionner tous les éléments (la coupe:). Par exemple, si x
est un tableau à 3 dimensions, x[0:2]
est identique à x[0:2,:,:]
et x[0:2,0:2]
est identique à x[0:2,0:2,]
.
L'opération de slicing de base de tableaux unidimensionnels est identique à celle d’une liste simple et le type renvoyé par une opération de slicing est compatible avec le tableau de départ.
>>> x = array([1.0,2.0,3.0,4.0,5.0])
>>> y = x[:]
array([ 1., 2., 3., 4., 5.])
>>> y = x[:2]
array([ 1., 2.])
>>> y = x[1::2]
array([ 2.,4.])
Pour les tableaux à $2$ dimensions, la première dimension spécifie la ou les lignes de la coupe et la seconde dimension spécifie la ou les colonnes.
Notons que la syntaxe de coupe en 2-dimensions y[a:b,c:d]
est la même que y[a:b,:][:,c:d]
ou y[a:b][:,c:d]
, bien que la version la plus courte soit préférée. Dans le cas où seul la coupe de lignes est nécessaire y[a:b]
, l'équivalent de y[a:b,:]
, est la syntaxe la plus courte.
>>> y = array([[0.0, 1, 2, 3, 4],[5, 6, 7, 8, 9]])
>>> y
array([[ 0., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 9.]])
>>> y[:1,:] # Row 0, all columns
array([[ 0., 1., 2., 3., 4.]])
>> y[:1] # Same as y[:1,:]
array([[ 0., 1., 2., 3., 4.]])
>>> y[:,:1] # all rows, column 0
array([[ 0.],
[ 5.]])
>>> y[:1,0:3] # Row 0, columns 0 to 2
array([[ 0., 1., 2.]])
>>> y[:1][:,0:3] # Same as previous
array([[ 0., 1., 2.]])
>>> y[:,3:] # All rows, columns 3 and 4
array([[ 3., 4.],
[ 8., 9.]])
>>> y = array([[[1.0,2],[3,4]],[[5,6],[7,8]]])
>>> y[:1,:,:] # Panel 0 of 3D y
array([[[ 1., 2.],
[ 3., 4.]]])
Lorsque les tableaux ont plus d'une dimension, il est souvent utile de combiner une sélection scalaire et par coupe (slicing) pour sélectionner une ligne, une colonne ou une partie entière d'un tableau à 3 dimensions. Ceci est similaire au slicing pur avec une mise en garde importante: les dimensions sélectionnées à l'aide de la sélection scalaire sont éliminées. Par exemple, si x
est un tableau à $2$ dimensions, alors x[0,:]
sélectionne la première ligne du tableau. Cependant, contrairement au tableau à 2 dimensions construit à l'aide de l'opération x[:1,:]
, x[0,:]
sera un tableau à 1 dimension.
>>> x = array([[1.0,2],[3,4]])
>>> x[:1,:] # Row 1, all columns, 2-dimensional
array([[ 1., 2.]])
>>> x[0,:] # Row 1, all columns, dimension reduced
array([ 1., 2.])
Bien que les deux sélections semblent similaires, la première produit un tableau à 2 dimensions (notons la syntaxe [[]]
), tandis que la seconde est un tableau à $1$ dimension. Dans la plupart des cas où une seule ligne ou une seule colonne est requise, l'utilisation de sélecteurs scalaires tels que y[0,:]
est la meilleure pratique.
Le principe adopté par NumPy est que l'opération de slicing doit toujours préserver la dimension du tableau sous-jacent, tandis que la sélection scalaire doit toujours réduire la ou les dimensions. Ceci est cohérent avec x[0,0]
retournant un scalaire (un tableau à $0$ dimensions) puisque les deux sélections sont scalaires. Ceci est démontré dans l'exemple suivant qui souligne les différences entre slicing pur, la sélection mixte et la sélection scalaire pure. Notons que la fonction ndim
renvoie le nombre de dimensions d’un tableau.
>>> x = array([[0.0, 1, 2, 3, 4],[5, 6, 7, 8, 9]])
>>> x[:1,:] # Row 0, all columns, 2-dimensional
array([[ 0., 1., 2., 3., 4.]])
>>> ndim(x[:1,:])
2
>>> x[0,:] # Row 0, all column, dim reduction to 1-d array
array([ 0., 1., 2., 3., 4.])
>>> ndim(x[0,:])
1
>>> x[0,0] # Top left element, dim reduction to scalar (0-d array)
0.0
>>> ndim(x[0,0])
0
>>> x[:,0] # All rows, 1 column, dim reduction to 1-d array
array([ 0., 5.])
La sélection par coupe (slicing) et la sélection scalaire peuvent être utilisés pour affecter des tableaux ayant la même dimension que la coupe.
>>> x = array([[0.0]*3]*3) # *3 repeats the list 3 times
>>> x
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
>>> x[0,:] = array([1.0, 2.0, 3.0])
>>> x
array([[ 1., 2., 3.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> x[::2,::2]
array([[ 1., 3.],
[ 0., 0.]])
>>> x[::2,::2] = array([[-99.0,-99],[-99,-99]]) # 2 by 2
>>> x
array([[-99., 2., -99.],
[0., 0., 0.],
[-99., 0., -99.]])
>>> x[1,1] = pi
>>> x
array([[-99., 2., -99.],
[ 0., 3.14159265, 0.],
[-99., 0., -99.]])
NumPy tente une conversion automatique des types de données si un élément est inséré dans un tableau avec un type différent. Par exemple, si un tableau a un type de données entier, si on place un flottant dans le tableau, celui-ci sera tronqué et stocké sous la forme d'un entier. Ceci est dangereux et dans la plupart des cas, les tableaux doivent être initialisés pour contenir des flottants, sauf si tout est sous contrôle.
>>> x = [0, 1, 2, 3, 4] # Integers
>>> y = array(x)
>>> y.dtype
dtype('int32')
>>> y[0] = 3.141592
>>> y
array([3, 1, 2, 3, 4])
>>> x = [0.0, 1, 2, 3, 4] # 1 Float makes all float
>>> y = array(x)
>>> y.dtype
dtype('float64')
>>> y[0] = 3.141592
>>> y
array([3.141592, 1., 2., 3., 4.])
flat
¶Le stockage des données d'une matrice se fait ligne après ligne. Cela peut être généralisé pour un tableau à plusieurs dimensions. Nous pouvons faire appel à la fonction flat
comme suit
import numpy as np
>>> y = np.reshape(np.arange(25.0),(5,5))
y
>>> y[0] # Same as y[0,:], first row
array([ 0., 1., 2., 3., 4.])
>>> y.flat[0] # Scalar slice, flat is 1-dimensional
0
>>> y[6] # Error
IndexError: index out of bounds
>>> y.flat[6] # Element 6
6.0
>>> y.flat[12:15]
array([12., 13., 14.])
>>> y.flat[:] # All element slice
array([[0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.,
11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21.,
22., 23., 24.]])
Propagation des modifications
>>> x = reshape(arange(4.0),(2,2))
>>> x
array([[ 0., 1.],
[ 2., 3.]])
>>> s1 = x[0,:] # First row
>>> s2 = x[:,0] # First column
>>> s1[0] = -3.14 # Assign first element
>>> s1
array([-3.14, 1. ])
>>> s2
array([-3.14, 2. ])
>>> x
array([[-3.14, 1.],
[ 2., 3.]])
Si on souhaite bloquer la propagation, on utilise la fonction copy
>>> x = reshape(arange(4.0),(2,2))
>>> s1 = copy(x[0,:]) # Function copy
>>> s2 = x[:,0].copy() # Method copy, more common
>>> s3 = array(x[0,:]) # Create a new array
>>> s1[0] = -3.14
>>> s1
array([-3.14, 1.])
>>> s2
array([ 0., 2.])
>>> s3
array([0., 1.])
>>> x[0,0]
array([[ 0., 1.],
[ 2., 3.]])
Il existe une exception à cette règle: lors de l'utilisation d'une sélection scalaire pure, la valeur (scalaire) renvoyée est toujours une copie.
>>> x = arange(5.0)
>>> y = x[0] # Pure scalar selection
>>> z = x[:1] # A pure slice
>>> y = -3.14
>>> y # y Changes
-3.14
>>> x # No propagation
array([ 0., 1., 2., 3., 4.])
>>> z # No changes to z either
array([ 0.])
>>> z[0] = -2.79
>>> y # No propagation since y used pure scalar selection
-3.14
>>> x # z is a view of x, so changes propagate
array([-2.79, 1., 2., 3., 4.])
Enfin, les assignations qui sont des résultats d'applications de fonctions créeront automatiquement une copie du tableau sous-jacent.
>>> x = array([[0.0, 1.0],[2.0,3.0]])
>>> y = x
>>> print(id(x),id(y)) # même id, même objet
129186368 129186368
>>> y = x + 1.0
>>> y
array([[ 1., 2.],
[ 3., 4.]])
>>> print(id(x),id(y))
129186368 129183104
>>> x # non modifié
array([[ 0., 1.],
[ 2., 3.]])
>>> y = exp(x)
>>> print(id(x),id(y))
129186368 129185120
Python, par défaut, n'a accès qu'à un petit nombre de types et de fonctions intégrés. La grande majorité des fonctions sont founies par des modules. Avant de pouvoir accéder à une fonction, le module contenant cette fonction doit être importé. Par exemple, lors de l'utilisation de %pylab
dans une session IPython, un grand nombre de modules sont automatiquement importés, notamment NumPy, SciPy et matplotlib.
import
peut être utilisé de différentes manières. Le plus simple est d'utiliser from module import*
qui importe toutes les fonctions du module. L'utilisation de la fonction import
peut être problématique. Il est possible qu'une fonction importée d'un module soit cachée par un autre import
d'un autre module. Il est conseillé d'importer seulement les fonctions nécessaires pour le programme.
from pylab import log2 # Will import log2 only
from scipy import log10 # Will import the log10 only
Souvent on utilise
import pylab
import scipy
import numpy
ou encore
import pylab as pl
import scipy as sp
import numpy as np
Cette seconde option est préférable pour contrôler la provenance des fonctions. Par exemple, on peut accéder à la fonction racine carrée issue de SciPy à l'aide de sp.sqrt
et celle issue de pylab à l'aide de pl.sqrt
.
Les appels aux fonctions ont des conventions différentes de celles de la plupart des autres expressions. La différence la plus importante est que les fonctions peuvent prendre plusieurs entrées et renvoyer plusieurs sorties. La structure générique d'un appel de fonction est out1, out2, out3,. . . = functionname(in1, in2, in3,...).
La plupart des fonctions ont des arguments requis. Par exemple, considérons la définition de array
à partir de help(array)
,
array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
. array
possède un seul argument dit requis object
qui est une liste ou un tuple qui contient les données destinées à la création du tableau. L'aide de la fonction permet de lister les arguments où la plupart des arguments sont de la forme keyword=default
à l'exception de object
qui est un argument requis qui ne possède pas de valeur par défaut.
>>> array([[1.0,2.0],[3.0,4.0]])
array([[ 1., 2.],
[ 3., 4.]])
>>> array([[1.0,2.0],[3.0,4.0]], 'int32')
array([[1, 2],
[3, 4]])
array(object=[[1.0,2.0],[3.0,4.0]])
array([[1.0,2.0],[3.0,4.0]], dtype=None, copy=True, order=None, subok=False, ndmin=0)
Les arguments keyword de mots présentent deux avantages importants. Premièrement, ils ne doivent apparaître dans aucun ordre (Remarque: les arguments de classement aléatoire ne sont pas une bonne pratique et il ne s'agit que d'un exemple), et deuxièmement, les arguments keyword ne peuvent être utilisés qu'en cas de besoin, car une valeur par défaut est toujours fournie.
>>> array(dtype='complex64', object = [[1.0,2.0],[3.0,4.0]], copy=True)
array([[1.+0.j, 2.+0.j],
[3.+0.j, 4.+0.j]], dtype=complex64)
Les fonctions ont des valeurs par défaut pour les arguments optionnels. Celles-ci sont répertoriées dans la définition de la fonction et apparaissent dans l'aide sous la forme keyword=default. En retournant au tableau, toutes les entrées ont des arguments par défaut, à l'exception de object, le argument requis.
Certaines fonctions peuvent avoir plus d’une sortie. Ces fonctions peuvent être utilisées en mode de sortie unique ou en mode de sortie multiple. Par exemple, shape
peut être utilisée sur un tableau pour déterminer la taille de chaque dimension.
>>> x = array([[1.0,2.0],[3.0,4.0]])
>>> s = shape(x)
>>> s
(2, 2)
Comme la forme retournera autant de sorties qu'il y a de dimensions, elle peut être appelée avec 2 sorties lorsque l'entrée est un tableau à 2 dimensions.
>>> x = array([[1.0,2.0],[3.0,4.0]])
>>> M, N = shape(x)
>>> M
2
>>> N
2
Demander plus de sorties que nécessaire produit une erreur.
>>> M, N, P = shape(x) # Error
ValueError: need more than 2 values to unpack
De même, fournir peu de sorties peut aussi générer une erreur. Prenons le cas d'un tableau à 3 dimensions.
>>> x = randn(10,10,10)
>>> shape(x)
(10, 10, 10)
>>> M, N = shape(x) # Error
ValueError: too many values to unpack
import os as os
import numpy as np
M=np.random.randn(10,10)
print(M)
M.shape
## sauvegarder dans fichier csv
print(os.getcwd()) ## afficher le répertoire courant
#os.chdir(path) # pour changer de répertoire de travail
np.savetxt('data.csv',M,fmt='%2.2f',delimiter=',')
## on peut sauvegarder au format propre à numpy : npy
np.save('data.npy',M)
np.load('data.npy')
Identifier le résultat de chacune des instructions suivantes
#1.
v=np.array(range(5)) + 1
#2.
print(v)
#3.
v[1:4]
#4.
v[::]
#5.
v[ : :2]
#6.
v[ : 3]
#7.
v[3 :]
#8.
v[-1]
#9.
v[-2 :]
Identifier le résultat de chacune des instructions suivantes
#1.
M=random.rand(4,3)
#2.
ind=[1,2]
M[ind]
#3.
M[:,ind]
#4.
M[[0,2],[1,2]]
#5.
M[np.ix_([0,2],[1,2])]
#6.
(M>0.5)
#7.
M[M>0.5]
Identifier le résultat de chacune des instructions suivantes
#1.
a=np.array([[0,1],[2,3],[4,5]])
#2.
np.ndim(a)
#3.
np.size(a)
#4.
np.shape(a)
#5.
np.transpose(a)
#6.
a.T
#7.
a.min(), np.min(a)
#8.
a.sum(), np.sum(a)
#9.
a.sum(axis=0)
#10.
a.sum(axis=1)
#11.
np.r_[1:4,10,11]
#12.
np.c_[1:4,11:14]
#13.
np.arange(6).reshape(3,2)
#14.
A=np.array([[1,2],[3,4]])
np.tile(A,(3,2))
#15.
A=np.array([[1,2],[3,4]])
B=np.array([[11,12],[13,14]])
np.concatenate((A,B),axis=0)
#16.
np.vstack((A,B))
#17.
np.concatenate((A,B),axis=1)
#18.
np.hstack((A,B))
Identifier le résultat de chacune des instructions suivantes
#1.
a=np.arange(6).reshape(3,2)
b=np.arange(3,9).reshape(3,2)
c=np.transpose(b)
a+b
#2.
a*b
#3.
np.dot(a,c)
#4.
np.power(a,2)
#5.
np.power(2,a)
#6.
a/3
#7.
import numpy as np
from scipy import linalg
#8.
A = np.array([[1,2],[3,4]])
linalg.inv(A)
#9.
linalg.det(A)
#10.
la,v = linalg.eig(A)
l1,l2 = la
print(l1, l2)
#11.
print(v[:,0])
#12.
U,s,V = linalg.svd(A)
print(s**2)
#13.
linalg.eig(np.dot(np.transpose(A),A))