web-dev-qa-db-fra.com

supprimer des lignes dans un tableau numpy

J'ai un tableau qui pourrait ressembler à ceci:

ANOVAInputMatrixValuesArray = [[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 
0.53172222], [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]]

Notez que l'une des lignes a une valeur zéro à la fin. Je souhaite supprimer toute ligne contenant un zéro tout en conservant toute ligne contenant des valeurs non nulles dans toutes les cellules.

Mais le tableau aura un nombre différent de lignes à chaque fois qu'il est rempli et les zéros seront situés dans des lignes différentes à chaque fois.

J'obtiens le nombre d'éléments non nuls dans chaque ligne avec la ligne de code suivante:

NumNonzeroElementsInRows    = (ANOVAInputMatrixValuesArray != 0).sum(1)

Pour le tableau ci-dessus, NumNonzeroElementsInRows contient: [5 4]

Le chiffre cinq indique que toutes les valeurs possibles de la ligne 0 sont non nulles, tandis que le chiffre quatre indique que l'une des valeurs possibles de la ligne 1 est zéro.

Par conséquent, j'essaie d'utiliser les lignes de code suivantes pour rechercher et supprimer des lignes qui contiennent des valeurs nulles.

for q in range(len(NumNonzeroElementsInRows)):
    if NumNonzeroElementsInRows[q] < NumNonzeroElementsInRows.max():
        p.delete(ANOVAInputMatrixValuesArray, q, axis=0)

Mais pour une raison quelconque, ce code ne semble rien faire, même si de nombreuses commandes d'impression indiquent que toutes les variables semblent s'être renseignées correctement pour aboutir au code.

Il doit exister un moyen simple de simplement "supprimer toute ligne contenant une valeur nulle".

Quelqu'un peut-il me montrer quel code écrire pour accomplir cela?

67
MedicalMath

La méthode la plus simple pour supprimer des lignes et des colonnes des tableaux est la méthode numpy.delete.

Supposons que j'ai le tableau suivant x:

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

Pour supprimer la première ligne, procédez comme suit:

x = numpy.delete(x, (0), axis=0)

Pour supprimer la troisième colonne, procédez comme suit:

x = numpy.delete(x,(2), axis=1)

Ainsi, vous pouvez trouver les index des lignes contenant un 0, les mettre dans une liste ou un tuple et le transmettre comme second argument de la fonction.

125
Jaidev Deshpande

Voici un one-liner (oui, c'est similaire à user333700, mais un peu plus simple):

>>> import numpy as np
>>> arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222], 
                [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
>>> print arr[arr.all(1)]
array([[ 0.96488889,  0.73641667,  0.67521429,  0.592875  ,  0.53172222]])

À propos, cette méthode est beaucoup, beaucoup plus rapide que la méthode des tableaux masqués pour les grandes matrices. Pour une matrice de 2048 x 5, cette méthode est environ 1000 fois plus rapide.

À propos, la méthode de user333700 (d'après son commentaire) était légèrement plus rapide dans mes tests, bien que cela m'embarrasse à l'esprit.

13
Justin Peel

Ceci est similaire à votre approche initiale et utilisera moins d'espace que la réponse de unutbu , mais je suppose que ce sera plus lent.

>>> import numpy as np
>>> p = np.array([[1.5, 0], [1.4,1.5], [1.6, 0], [1.7, 1.8]])
>>> p
array([[ 1.5,  0. ],
       [ 1.4,  1.5],
       [ 1.6,  0. ],
       [ 1.7,  1.8]])
>>> nz = (p == 0).sum(1)
>>> q = p[nz == 0, :]
>>> q
array([[ 1.4,  1.5],
       [ 1.7,  1.8]])

En passant, votre ligne p.delete() ne fonctionne pas pour moi - ndarrays n'ont pas d'attribut .delete.

4
mtrw

numpy fournit une fonction simple permettant de faire exactement la même chose: en supposant que vous ayez un tableau masqué 'a', appeler numpy.ma.compress_rows (a) supprimera les lignes contenant une valeur masquée . Je suppose que c'est ainsi beaucoup plus vite de cette façon ...

2
jeps
import numpy as np 
arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222],[ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
print(arr[np.where(arr != 0.)])
0
Prokhozhii