97 votes

Extraire la partie triangulaire supérieure ou inférieure d'une matrice numpy

Je dispose d'une matrice A et je veux 2 matrices U et L telles que U contienne les éléments triangulaires supérieurs de A (tous les éléments au-dessus et non inclus la diagonale) et de même pour L (tous les éléments en dessous et non inclus la diagonale). Existe-t-il une méthode numpy pour faire cela?

par exemple

A = array([[ 4.,  9., -3.],
           [ 2.,  4., -2.],
           [-2., -3.,  7.]])

U = array([[ 0.,  9., -3.],
           [ 0.,  0., -2.],
           [ 0.,  0.,  0.]])

L = array([[ 0.,  0.,  0.],
           [ 2.,  0.,  0.],
           [-2., -3.,  0.]])

98voto

seralouk Points 5618

Pour extraire les valeurs du triangle supérieur vers un vecteur plat, vous pouvez faire quelque chose comme ce qui suit:

import numpy as np

a = np.array([[1,2,3],[4,5,6],[7,8,9])
print(a)

#array([[1, 2, 3],
#       [4, 5, 6],
#       [7, 8, 9]])

a[np.triu_indices(3)]
#ou
list(a[np.triu_indices(3)])

#array([1, 2, 3, 5, 6, 9])

De même, pour le triangle inférieur, utilisez np.tril.


IMPORTANT

Si vous voulez extraire les valeurs qui sont au-dessus de la diagonale (ou en dessous), utilisez l'argument k. Ceci est généralement utilisé lorsque la matrice est symétrique.

import numpy as np

a = np.array([[1,2,3],[4,5,6],[7,8,9]])

#array([[1, 2, 3],
#       [4, 5, 6],
#       [7, 8, 9]])

a[np.triu_indices(3, k = 1)]

# cela renvoie
array([2, 3, 6])

EDIT (le 11.11.2019):

Pour remettre le vecteur extrait dans un tableau symétrique en 2D, vous pouvez suivre ma réponse ici: https://stackoverflow.com/a/58806626/5025009

4 votes

Concis et facile à comprendre. Excellente réponse!

13 votes

Vous pouvez aussi utiliser np.triu_indices_from(a), vous n'avez donc pas besoin de spécifier manuellement la taille de la matrice.

97voto

mathematical.coffee Points 23150

Essayez numpy.triu (triangle-supérieur) et numpy.tril (triangle-inférieur).

Exemple de code:

np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 0,  8,  9],
       [ 0,  0, 12]])

43 votes

À l'auteur de la question : Il est souvent utile de savoir qu'ils prennent un argument k, aussi, pour extraire la diagonale au-dessus ou en-dessous (ce qui peut être vraiment utile quand vous en avez besoin !). De plus, il y a les fonctions np.triu_indices, np.tril_indices, np.triu_indices_from et np.tril_indices_from pour générer des indices pour indexer le triangle supérieur ou inférieur. (Les versions "from" prennent simplement un tableau d'entrée au lieu d'une forme)

22voto

Utilisez les Routines de création de tableaux de numpy.triu et numpy.tril pour renvoyer une copie d'une matrice avec les éléments au-dessus ou en-dessous de la k-ième diagonale mis à zéro.

    >>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
    >>> a
    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])

    >>> tri_upper_diag = np.triu(a, k=0)
    >>> tri_upper_diag
    array([[1, 2, 3],
           [0, 5, 6],
           [0, 0, 9]])

    >>> tri_upper_no_diag = np.triu(a, k=1)
    >>> tri_upper_no_diag
    array([[0, 2, 3],
           [0, 0, 6],
           [0, 0, 0]])

    >>> tri_lower_diag = np.tril(a, k=0)
    >>> tri_lower_diag
    array([[1, 0, 0],
           [4, 5, 0],
           [7, 8, 9]])

    >>> tri_lower_no_diag = np.tril(a, k=-1)
    >>> tri_lower_no_diag
    array([[0, 0, 0],
           [4, 0, 0],
           [7, 8, 0]])

4 votes

Comment rempliriez-vous avec autre chose que 0, la ligne np.inf par exemple?

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