4.1. Création d’un tableau#
Le module numpy
est un outil performant pour la manipulation de tableaux à plusieurs dimensions. Il ajoute en effet la classe array
qui a des similarités avec les listes mais tous les éléments sont obligatoirement du même type : soit des entiers, soit des flotants, soit des booléens…
Nous commençons par charger le module numpy
et nous lui donnons un alias pour raccourcir son appel (l’alias np
n’est pas obligatoire mais dans la pratique, tout le monde l’utilise).
import numpy as np
help(np.array)
Help on built-in function array in module numpy:
array(...)
array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0,
like=None)
Create an array.
Parameters
----------
object : array_like
An array, any object exposing the array interface, an object whose
``__array__`` method returns an array, or any (nested) sequence.
If object is a scalar, a 0-dimensional array containing object is
returned.
dtype : data-type, optional
The desired data-type for the array. If not given, NumPy will try to use
a default ``dtype`` that can represent the values (by applying promotion
rules when necessary.)
copy : bool, optional
If true (default), then the object is copied. Otherwise, a copy will
only be made if ``__array__`` returns a copy, if obj is a nested
sequence, or if a copy is needed to satisfy any of the other
requirements (``dtype``, ``order``, etc.).
order : {'K', 'A', 'C', 'F'}, optional
Specify the memory layout of the array. If object is not an array, the
newly created array will be in C order (row major) unless 'F' is
specified, in which case it will be in Fortran order (column major).
If object is an array the following holds.
===== ========= ===================================================
order no copy copy=True
===== ========= ===================================================
'K' unchanged F & C order preserved, otherwise most similar order
'A' unchanged F order if input is F and not C, otherwise C order
'C' C order C order
'F' F order F order
===== ========= ===================================================
When ``copy=False`` and a copy is made for other reasons, the result is
the same as if ``copy=True``, with some exceptions for 'A', see the
Notes section. The default order is 'K'.
subok : bool, optional
If True, then sub-classes will be passed-through, otherwise
the returned array will be forced to be a base-class array (default).
ndmin : int, optional
Specifies the minimum number of dimensions that the resulting
array should have. Ones will be prepended to the shape as
needed to meet this requirement.
like : array_like, optional
Reference object to allow the creation of arrays which are not
NumPy arrays. If an array-like passed in as ``like`` supports
the ``__array_function__`` protocol, the result will be defined
by it. In this case, it ensures the creation of an array object
compatible with that passed in via this argument.
.. versionadded:: 1.20.0
Returns
-------
out : ndarray
An array object satisfying the specified requirements.
See Also
--------
empty_like : Return an empty array with shape and type of input.
ones_like : Return an array of ones with shape and type of input.
zeros_like : Return an array of zeros with shape and type of input.
full_like : Return a new array with shape of input filled with value.
empty : Return a new uninitialized array.
ones : Return a new array setting values to one.
zeros : Return a new array setting values to zero.
full : Return a new array of given shape filled with value.
Notes
-----
When order is 'A' and ``object`` is an array in neither 'C' nor 'F' order,
and a copy is forced by a change in dtype, then the order of the result is
not necessarily 'C' as expected. This is likely a bug.
Examples
--------
>>> np.array([1, 2, 3])
array([1, 2, 3])
Upcasting:
>>> np.array([1, 2, 3.0])
array([ 1., 2., 3.])
More than one dimension:
>>> np.array([[1, 2], [3, 4]])
array([[1, 2],
[3, 4]])
Minimum dimensions 2:
>>> np.array([1, 2, 3], ndmin=2)
array([[1, 2, 3]])
Type provided:
>>> np.array([1, 2, 3], dtype=complex)
array([ 1.+0.j, 2.+0.j, 3.+0.j])
Data-type consisting of more than one element:
>>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')])
>>> x['a']
array([1, 3])
Creating an array from sub-classes:
>>> np.array(np.mat('1 2; 3 4'))
array([[1, 2],
[3, 4]])
>>> np.array(np.mat('1 2; 3 4'), subok=True)
matrix([[1, 2],
[3, 4]])
Interdit
Vous verrez souvent l’importation sous la forme
from numpy import *
C’est dangereux pour plusieurs raisons
cela place touts les objets créés dans
numpy
dans l’espace de nom, quitte à écraser des choses que vous avez pu y mettre avant, ou pire, vous pouvez écraser des objetsnumpy
sans le faire exprès ensuite…c’est très lourd car en général, vous n’avez pas besoin de charger tous les objets, seulement quelques uns.
Dans la documentation
python
, cette syntaxe est réservée au développeur d’un module, c’est interdit pour les utilisateurs. Mais enpython
, tout est ouvert !
############## INTERDIT ##################
from numpy import *
print(exp(1))
def exp(x): # on écrase la fonction exponentielle de python
return x
print(exp(1))
2.718281828459045
1
############## SYNTAXE CORRECTE ##################
import numpy as np
import math
print(np.exp(1))
print(math.exp(1))
print(exp(1))
2.718281828459045
2.718281828459045
1
4.1.1. … à partir d’une liste#
Cela permet en particulier de remplir à la main des petits tableaux ou bien d’utiliser de manière astucieuses la compréhension de liste. On utilise pour cela la commande array
qui transforme une liste en un tableau.
Voici quelques exemples :
# création d'un tableau d'entiers
A = np.array([1, 2, 3])
print(type(A), A, A.dtype)
# création d'un tableau de réels
A = np.array([1., 2, 3])
print(type(A), A, A.dtype)
<class 'numpy.ndarray'> [1 2 3] int64
<class 'numpy.ndarray'> [1. 2. 3.] float64
# tableau à deux dimensions
A = np.array(
[
[1, 2, 3],
[2, 3, 4]
]
)
print(A)
[[1 2 3]
[2 3 4]]
# Avec compréhension de liste
A = np.array([k**2/2 for k in range(-3, 4)])
print(A)
[4.5 2. 0.5 0. 0.5 2. 4.5]
# Un exemple en dimension 2 pour faire une matrice
N = 10
B = np.array([
[k*l for l in range(N+1)] for k in range(N+1)
])
print(B)
[[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 2 4 6 8 10 12 14 16 18 20]
[ 0 3 6 9 12 15 18 21 24 27 30]
[ 0 4 8 12 16 20 24 28 32 36 40]
[ 0 5 10 15 20 25 30 35 40 45 50]
[ 0 6 12 18 24 30 36 42 48 54 60]
[ 0 7 14 21 28 35 42 49 56 63 70]
[ 0 8 16 24 32 40 48 56 64 72 80]
[ 0 9 18 27 36 45 54 63 72 81 90]
[ 0 10 20 30 40 50 60 70 80 90 100]]
4.1.2. … à partir de commandes toutes prêtes#
Il existe un grand nombre de tableaux connus que l’on peut créer à l’aide de commandes. Par exemple des tableaux vides, remplis de 0 ou de 1, des matrices diagonales, des nombres équirépartis entre 2 valeurs… Les commandes à connaitre sont les suivantes : (mais ce ne seront peut-être pas les seules que nous utiliserons !)
np.empty
,np.zeros
,np.ones
,np.random.rand
;np.eye
,np.identity
,np.diag
,np.triu
,np.tril
;np.arange
,np.linspace
.
nx, ny = 5, 4
# tableaux à 1 dimension
print(np.empty((nx,)))
print(np.zeros((nx,)))
print(np.zeros(nx))
print(np.ones((nx,)))
print(np.ones(nx))
[ 1. 2.75 6. 10.75 17. ]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
# tableaux à 2 dimensions
print(np.empty((nx, ny)))
print(np.zeros((nx, ny)))
print(np.ones((nx, ny)))
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
# on peut ajouter des dimensions...
print(np.zeros((2, 2, 2)))
[[[0. 0.]
[0. 0.]]
[[0. 0.]
[0. 0.]]]
# pour faire des tableaux alétoires
print(np.random.rand(5))
print(np.random.rand(5, 5))
[0.85954498 0.21746794 0.79150153 0.19093383 0.0806769 ]
[[0.08317723 0.52181931 0.16622842 0.62375554 0.60507569]
[0.38867929 0.11316953 0.03358762 0.85741732 0.02151827]
[0.21722901 0.43661586 0.14173333 0.07134532 0.4135922 ]
[0.74214346 0.35579988 0.21248817 0.7786657 0.94222406]
[0.42724428 0.30349238 0.45721447 0.82690077 0.55496278]]
help(np.zeros)
Help on built-in function zeros in module numpy:
zeros(...)
zeros(shape, dtype=float, order='C', *, like=None)
Return a new array of given shape and type, filled with zeros.
Parameters
----------
shape : int or tuple of ints
Shape of the new array, e.g., ``(2, 3)`` or ``2``.
dtype : data-type, optional
The desired data-type for the array, e.g., `numpy.int8`. Default is
`numpy.float64`.
order : {'C', 'F'}, optional, default: 'C'
Whether to store multi-dimensional data in row-major
(C-style) or column-major (Fortran-style) order in
memory.
like : array_like, optional
Reference object to allow the creation of arrays which are not
NumPy arrays. If an array-like passed in as ``like`` supports
the ``__array_function__`` protocol, the result will be defined
by it. In this case, it ensures the creation of an array object
compatible with that passed in via this argument.
.. versionadded:: 1.20.0
Returns
-------
out : ndarray
Array of zeros with the given shape, dtype, and order.
See Also
--------
zeros_like : Return an array of zeros with shape and type of input.
empty : Return a new uninitialized array.
ones : Return a new array setting values to one.
full : Return a new array of given shape filled with value.
Examples
--------
>>> np.zeros(5)
array([ 0., 0., 0., 0., 0.])
>>> np.zeros((5,), dtype=int)
array([0, 0, 0, 0, 0])
>>> np.zeros((2, 1))
array([[ 0.],
[ 0.]])
>>> s = (2,2)
>>> np.zeros(s)
array([[ 0., 0.],
[ 0., 0.]])
>>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
array([(0, 0), (0, 0)],
dtype=[('x', '<i4'), ('y', '<i4')])
help(np.eye)
Help on function eye in module numpy:
eye(N, M=None, k=0, dtype=<class 'float'>, order='C', *, like=None)
Return a 2-D array with ones on the diagonal and zeros elsewhere.
Parameters
----------
N : int
Number of rows in the output.
M : int, optional
Number of columns in the output. If None, defaults to `N`.
k : int, optional
Index of the diagonal: 0 (the default) refers to the main diagonal,
a positive value refers to an upper diagonal, and a negative value
to a lower diagonal.
dtype : data-type, optional
Data-type of the returned array.
order : {'C', 'F'}, optional
Whether the output should be stored in row-major (C-style) or
column-major (Fortran-style) order in memory.
.. versionadded:: 1.14.0
like : array_like, optional
Reference object to allow the creation of arrays which are not
NumPy arrays. If an array-like passed in as ``like`` supports
the ``__array_function__`` protocol, the result will be defined
by it. In this case, it ensures the creation of an array object
compatible with that passed in via this argument.
.. versionadded:: 1.20.0
Returns
-------
I : ndarray of shape (N,M)
An array where all elements are equal to zero, except for the `k`-th
diagonal, whose values are equal to one.
See Also
--------
identity : (almost) equivalent function
diag : diagonal 2-D array from a 1-D array specified by the user.
Examples
--------
>>> np.eye(2, dtype=int)
array([[1, 0],
[0, 1]])
>>> np.eye(3, k=1)
array([[0., 1., 0.],
[0., 0., 1.],
[0., 0., 0.]])
import numpy as np
N = 5
A = 2*np.eye(N, N, k=0) - np.eye(N, N, k=-1) - np.eye(N, N, k=1)
print(A)
[[ 2. -1. 0. 0. 0.]
[-1. 2. -1. 0. 0.]
[ 0. -1. 2. -1. 0.]
[ 0. 0. -1. 2. -1.]
[ 0. 0. 0. -1. 2.]]
help(np.diag)
Help on _ArrayFunctionDispatcher in module numpy:
diag(v, k=0)
Extract a diagonal or construct a diagonal array.
See the more detailed documentation for ``numpy.diagonal`` if you use this
function to extract a diagonal and wish to write to the resulting array;
whether it returns a copy or a view depends on what version of numpy you
are using.
Parameters
----------
v : array_like
If `v` is a 2-D array, return a copy of its `k`-th diagonal.
If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th
diagonal.
k : int, optional
Diagonal in question. The default is 0. Use `k>0` for diagonals
above the main diagonal, and `k<0` for diagonals below the main
diagonal.
Returns
-------
out : ndarray
The extracted diagonal or constructed diagonal array.
See Also
--------
diagonal : Return specified diagonals.
diagflat : Create a 2-D array with the flattened input as a diagonal.
trace : Sum along diagonals.
triu : Upper triangle of an array.
tril : Lower triangle of an array.
Examples
--------
>>> x = np.arange(9).reshape((3,3))
>>> x
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> np.diag(x)
array([0, 4, 8])
>>> np.diag(x, k=1)
array([1, 5])
>>> np.diag(x, k=-1)
array([3, 7])
>>> np.diag(np.diag(x))
array([[0, 0, 0],
[0, 4, 0],
[0, 0, 8]])
x = np.random.rand(5)
print(x)
A = np.diag(x) + np.diag(x[1:], k=1) + np.diag(x[1:], k=-1)
print(A)
[0.70498023 0.56704263 0.19277841 0.6465539 0.70100521]
[[0.70498023 0.56704263 0. 0. 0. ]
[0.56704263 0.56704263 0.19277841 0. 0. ]
[0. 0.19277841 0.19277841 0.6465539 0. ]
[0. 0. 0.6465539 0.6465539 0.70100521]
[0. 0. 0. 0.70100521 0.70100521]]
# On peut aussi récupérer la partie triangulaire supérieure
# (ou la partie triangulaire inférieure) d'une matrice
A = np.random.rand(5, 5)
print(np.triu(A))
print(np.triu(A, k=-1))
[[0.97266369 0.41618611 0.02448125 0.70002191 0.16375673]
[0. 0.84143618 0.39129594 0.1946312 0.07440549]
[0. 0. 0.48515467 0.69793087 0.91151479]
[0. 0. 0. 0.98375133 0.01041365]
[0. 0. 0. 0. 0.31280995]]
[[0.97266369 0.41618611 0.02448125 0.70002191 0.16375673]
[0.44342782 0.84143618 0.39129594 0.1946312 0.07440549]
[0. 0.39792463 0.48515467 0.69793087 0.91151479]
[0. 0. 0.7966201 0.98375133 0.01041365]
[0. 0. 0. 0.40983154 0.31280995]]
# points équi-répartis entre a et b par pas de dx : np.arange(a, b, dx)
print(np.arange(10))
print(np.arange(2, 10))
print(np.arange(2, 10, 0.5))
# N points équi-répartis entre a et b : np.linspace(a, b, N)
print(np.linspace(0, 1, 11))
print(np.linspace(0, 1, 10, endpoint=False))
[0 1 2 3 4 5 6 7 8 9]
[2 3 4 5 6 7 8 9]
[2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. 6.5 7. 7.5 8. 8.5 9. 9.5]
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
4.1.3. … à partir d’une fonction#
Il est aussi possible de créer un tableau à partir d’une fonction sur les indices du tableau. Par exemple, pour un tableau de dimension 1
ou en dimension 2
On utilise pour le cela la commande np.fromfunction
qui prend en argument une fonction (attention, par défaut les indices i
, j
, … passés en argument à la fonction sont des float
) et la forme du tableau sous la forme d’un tuple.
i = np.arange(10)
print(3*i+1.)
print(np.fromfunction(lambda i: 3*i+1, (10,)))
[ 1. 4. 7. 10. 13. 16. 19. 22. 25. 28.]
[ 1. 4. 7. 10. 13. 16. 19. 22. 25. 28.]
N = 6
hilbert = lambda i, j: 1/(i+j+1)
print(np.fromfunction(hilbert, (N, N)))
[[1. 0.5 0.33333333 0.25 0.2 0.16666667]
[0.5 0.33333333 0.25 0.2 0.16666667 0.14285714]
[0.33333333 0.25 0.2 0.16666667 0.14285714 0.125 ]
[0.25 0.2 0.16666667 0.14285714 0.125 0.11111111]
[0.2 0.16666667 0.14285714 0.125 0.11111111 0.1 ]
[0.16666667 0.14285714 0.125 0.11111111 0.1 0.09090909]]
x = np.arange(10)
print(np.fromfunction(lambda i, j: x[(i+j) % x.size], (x.size, x.size), dtype=int))
[[0 1 2 3 4 5 6 7 8 9]
[1 2 3 4 5 6 7 8 9 0]
[2 3 4 5 6 7 8 9 0 1]
[3 4 5 6 7 8 9 0 1 2]
[4 5 6 7 8 9 0 1 2 3]
[5 6 7 8 9 0 1 2 3 4]
[6 7 8 9 0 1 2 3 4 5]
[7 8 9 0 1 2 3 4 5 6]
[8 9 0 1 2 3 4 5 6 7]
[9 0 1 2 3 4 5 6 7 8]]
help(np.fromfunction)
Help on function fromfunction in module numpy:
fromfunction(function, shape, *, dtype=<class 'float'>, like=None, **kwargs)
Construct an array by executing a function over each coordinate.
The resulting array therefore has a value ``fn(x, y, z)`` at
coordinate ``(x, y, z)``.
Parameters
----------
function : callable
The function is called with N parameters, where N is the rank of
`shape`. Each parameter represents the coordinates of the array
varying along a specific axis. For example, if `shape`
were ``(2, 2)``, then the parameters would be
``array([[0, 0], [1, 1]])`` and ``array([[0, 1], [0, 1]])``
shape : (N,) tuple of ints
Shape of the output array, which also determines the shape of
the coordinate arrays passed to `function`.
dtype : data-type, optional
Data-type of the coordinate arrays passed to `function`.
By default, `dtype` is float.
like : array_like, optional
Reference object to allow the creation of arrays which are not
NumPy arrays. If an array-like passed in as ``like`` supports
the ``__array_function__`` protocol, the result will be defined
by it. In this case, it ensures the creation of an array object
compatible with that passed in via this argument.
.. versionadded:: 1.20.0
Returns
-------
fromfunction : any
The result of the call to `function` is passed back directly.
Therefore the shape of `fromfunction` is completely determined by
`function`. If `function` returns a scalar value, the shape of
`fromfunction` would not match the `shape` parameter.
See Also
--------
indices, meshgrid
Notes
-----
Keywords other than `dtype` and `like` are passed to `function`.
Examples
--------
>>> np.fromfunction(lambda i, j: i, (2, 2), dtype=float)
array([[0., 0.],
[1., 1.]])
>>> np.fromfunction(lambda i, j: j, (2, 2), dtype=float)
array([[0., 1.],
[0., 1.]])
>>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
array([[ True, False, False],
[False, True, False],
[False, False, True]])
>>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])