427 votes

Quelles sont les différences entre les tableaux et les matrices numpy ? Lequel dois-je utiliser ?

Quels sont les avantages et les inconvénients de chacun ?

D'après ce que j'ai vu, l'un ou l'autre peut remplacer l'autre en cas de besoin, alors dois-je prendre la peine d'utiliser les deux ou dois-je m'en tenir à l'un d'entre eux ?

Le style du programme influencera-t-il mon choix ? Je fais de l'apprentissage automatique en utilisant numpy, donc il y a effectivement beaucoup de matrices, mais aussi beaucoup de vecteurs (tableaux).

3 votes

Je n'ai pas assez d'informations pour justifier une réponse mais d'après ce que je peux dire, la principale différence est l'implémentation de la multiplication. Une matrice effectue une multiplication matricielle/tensorielle, tandis qu'un tableau effectue une multiplication par élément.

9 votes

Python 3.5 a ajouté l'opérateur infixe @ pour la multiplication matricielle (PEP 465), et NumPy 1.10 a ajouté le support de cet opérateur. Donc, si vous utilisez Python 3.5+ et NumPy 1.10+, vous pouvez simplement écrire A @ B au lieu de A.dot(B)A et B sont des 2D ndarray s. Cela supprime le principal avantage de l'utilisation de matrix au lieu d'un simple ndarray s, IMHO.

467voto

unutbu Points 222216

Numpy matrices sont strictement bidimensionnels, tandis que numpy tableaux (ndarrays) sont N-dimensionnelles. Les objets Matrix sont une sous-classe de ndarray, ils héritent donc de tous les attributs et méthodes des ndarrays.

Le principal avantage des matrices numpy est qu'elles fournissent une notation pratique pour la multiplication de matrices : si a et b sont des matrices, alors a*b est leur produit matriciel produit.

import numpy as np

a = np.mat('4 3; 2 1')
b = np.mat('1 2; 3 4')
print(a)
# [[4 3]
#  [2 1]]
print(b)
# [[1 2]
#  [3 4]]
print(a*b)
# [[13 20]
#  [ 5  8]]

D'autre part, à partir de Python 3.5, NumPy prend en charge la multiplication de matrices infixes à l'aide de la fonction @ de sorte que vous pouvez obtenir la même commodité de multiplication matricielle avec des ndarrays dans Python >= 3.5.

import numpy as np

a = np.array([[4, 3], [2, 1]])
b = np.array([[1, 2], [3, 4]])
print(a@b)
# [[13 20]
#  [ 5  8]]

Les objets matriciels et les ndarrays ont tous les deux .T pour retourner la transposition, mais les objets matriciels ont également .H pour la transposition conjuguée, et .I pour l'inverse.

En revanche, les tableaux numpy respectent systématiquement la règle selon laquelle les opérations sont appliquées par éléments (à l'exception de new). sont appliquées élément par élément (sauf pour la nouvelle @ ). Ainsi, si a et b sont des tableaux numpy, alors a*b est le tableau formé par la multiplication des composants par élément :

c = np.array([[4, 3], [2, 1]])
d = np.array([[1, 2], [3, 4]])
print(c*d)
# [[4 6]
#  [6 4]]

Pour obtenir le résultat d'une multiplication matricielle, on utilise np.dot (ou @ dans Python >= 3.5, comme indiqué ci-dessus) :

print(np.dot(c,d))
# [[13 20]
#  [ 5  8]]

Le site ** se comporte également différemment :

print(a**2)
# [[22 15]
#  [10  7]]
print(c**2)
# [[16  9]
#  [ 4  1]]

Depuis a est une matrice, a**2 renvoie le produit matriciel a*a . Puisque c est un ndarray, c**2 renvoie un ndarray avec chaque composant élevé au carré par élément.

Il existe d'autres différences techniques entre les objets matriciels et les ndarrays (en rapport avec np.ravel la sélection des éléments et le comportement des séquences).

Le principal avantage des tableaux numpy est qu'ils sont plus généraux que les matrices à 2 dimensions . Que se passe-t-il lorsque vous voulez un tableau à 3 dimensions ? Dans ce cas, vous devez utiliser un ndarray, et non un objet matrice. Ainsi, apprendre à utiliser matrix matricielle demande plus de travail - vous devez apprendre les opérations sur les objets matriciels et les opérations sur les tableaux. les opérations sur les ndarray.

Écrire un programme qui mélange à la fois des matrices et des tableaux vous rend la vie difficile parce que vous devez garder la trace du type d'objet de vos variables, de peur que la multiplication ne renvoie quelque chose d'inattendu.

En revanche, si vous vous en tenez uniquement aux ndarrays, vous pouvez faire tout ce que les objets matriciels peuvent faire et plus encore, mais avec des caractéristiques légèrement différentes. ce que les objets matriciels peuvent faire, et plus encore, mais avec des fonctions/notations fonctions/notation légèrement différentes.

Si vous êtes prêt à renoncer à l'attrait visuel de la notation du produit matriciel NumPy (qui peut être obtenue de manière presque aussi élégante avec ndarrays dans Python >= 3.5), alors je pense que les tableaux NumPy sont définitivement la voie à suivre.

PS. Bien sûr, vous n'êtes pas obligé de choisir l'un au détriment de l'autre, puisque np.asmatrix et np.asarray vous permettent de convertir l'un en l'autre (à condition que le tableau est bidimensionnel).


Il y a un synopsis des différences entre NumPy arrays vs NumPy matrix es ici .

11 votes

Pour ceux qui se demandent, mat**n pour une matrice peut être appliquée de manière inélégante à un tableau avec reduce(np.dot, [arr]*n)

14 votes

Ou juste np.linalg.matrix_power(mat, n)

0 votes

Je me demande si les matrices seraient plus rapides... on pourrait penser qu'elles doivent effectuer moins de vérifications que ndarray.

100voto

atomh33ls Points 2461

Scipy.org vous recommande d'utiliser des tableaux :

*array " ou " matrix " ? Lequel dois-je utiliser ? - Réponse courte

Utilisez des tableaux.

  • Ils sont le type standard de vecteur/matrice/tenseur de numpy. De nombreuses fonctions numpy retournent des tableaux, pas des matrices.

  • Il existe une distinction claire entre les opérations par éléments et les opérations d'algèbre linéaire. les opérations d'algèbre linéaire.

  • Vous pouvez avoir des vecteurs standard ou des vecteurs ligne/colonne si vous le souhaitez.

Le seul inconvénient de l'utilisation du type tableau est que vous devrez utiliser dot au lieu de * pour multiplier (réduire) deux tenseurs (produit scalaire, multiplication vectorielle matricielle, etc.)

11 votes

Même si la réponse acceptée fournit plus d'informations, la vraie réponse est en effet de s'en tenir à ndarray . Le principal argument en faveur de l'utilisation de matrix serait si votre code est lourd en algèbre linéaire et aurait l'air moins clair avec tous les appels à la fonction dot fonction. Mais cet argument disparaîtra à l'avenir, maintenant que l'opérateur @ est accepté pour une utilisation avec la multiplication de matrice, voir PEP 465 . Cela nécessite Python 3.5 et la dernière version de Numpy. La classe matrix pourrait être dépréciée dans un futur proche, il est donc préférable d'utiliser ndarray pour le nouveau code ...

7 votes

Cette page oublie gracieusement scipy.sparse matrices. Si vous utilisez à la fois des matrices denses et des matrices éparses dans votre code, il est beaucoup plus facile de s'en tenir aux règles suivantes matrix .

4 votes

À mon avis, le principal inconvénient des tableaux est que le découpage en colonnes renvoie des tableaux plats, ce qui peut être déroutant et n'est pas vraiment valable d'un point de vue mathématique. Cela conduit également à l'inconvénient important que les tableaux numpy ne peuvent pas être traités de la même manière que les matrices scipy.sparse alors que les matrices numpy peuvent être échangées librement avec les matrices sparse. Dans ce contexte, il est un peu absurde que scipy recommande l'utilisation des tableaux et qu'il ne fournisse pas de tableaux sparse compatibles.

31voto

user333700 Points 4749

Juste pour ajouter un cas à la liste d'unutbu.

Une des plus grandes différences pratiques pour moi de numpy ndarrays par rapport à numpy matrices ou des langages matriciels comme matlab, est que la dimension n'est pas préservée dans les opérations de réduction. Les matrices sont toujours 2d, alors que la moyenne d'un tableau, par exemple, a une dimension en moins.

Par exemple, démêler les lignes d'une matrice ou d'un tableau :

avec la matrice

>>> m = np.mat([[1,2],[2,3]])
>>> m
matrix([[1, 2],
        [2, 3]])
>>> mm = m.mean(1)
>>> mm
matrix([[ 1.5],
        [ 2.5]])
>>> mm.shape
(2, 1)
>>> m - mm
matrix([[-0.5,  0.5],
        [-0.5,  0.5]])

avec tableau

>>> a = np.array([[1,2],[2,3]])
>>> a
array([[1, 2],
       [2, 3]])
>>> am = a.mean(1)
>>> am.shape
(2,)
>>> am
array([ 1.5,  2.5])
>>> a - am #wrong
array([[-0.5, -0.5],
       [ 0.5,  0.5]])
>>> a - am[:, np.newaxis]  #right
array([[-0.5,  0.5],
       [-0.5,  0.5]])

Je pense également que le mélange de tableaux et de matrices donne lieu à de nombreuses heures de débogage "heureuses". Cependant, les matrices scipy.sparse sont toujours des matrices en termes d'opérateurs comme la multiplication.

30voto

Aks Points 385

D'après les documents officiels, il n'est plus conseillé d'utiliser la classe matrice car elle sera supprimée à l'avenir.

https://numpy.org/doc/stable/reference/generated/numpy.matrix.html

Comme d'autres réponses l'indiquent déjà, vous pouvez effectuer toutes les opérations avec des tableaux NumPy.

23voto

Peque Points 504

Comme d'autres l'ont mentionné, l'avantage principal de l'approche de la matrix était qu'il fournissait une notation pratique pour la multiplication des matrices.

Cependant, dans Python 3.5, il y a enfin un opérateur infixe dédié à la multiplication de matrices : @ .

Avec les versions récentes de NumPy, il peut être utilisé avec ndarray s :

A = numpy.ones((1, 3))
B = numpy.ones((3, 3))
A @ B

Donc, aujourd'hui, encore plus, en cas de doute, vous devez vous en tenir à ndarray .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X