J'ai un tableau multidimensionnel similaire au suivant et j'essaie de supprimer les chaînes qui se terminent par * (étoiles) afin que je puisse le convertir en un tableau de flotteurs.

    array1 = np.column_stack((a, b, c, d)) 
    array1 = np.array([
       ['*0.70*', '21.59', '4.37', '21.70'],
       ['2.15', '21.42', '5.63', '22.33'],
       ['*8.00*', '21.17', '5.11', '22.40'],
       ['2.36', '22.88', '*2.54*', '*20.95*'],
       ['2.07', '22.64', '6.68', '22.26']
       ])

Y a-t-il un moyen pour nous np.where de donner la coordonnée dans le tableau de la valeur mise en évidence avec des étoiles, et pas seulement un index pour que je puisse supprimer la ligne entière?

Donc, la sortie idéale serait quelque chose dans le sens de K

fil1 = np.where(np.char.endswith(array1, "*") == True)

print(fil1) 
(0,0), (0,2), (2, 3), (3, 3)
1
KGreen 27 mai 2020 à 16:09

3 réponses

Meilleure réponse

np.where renvoie 1 tableau par dimension. Si vous voulez connaître les indices des lignes contenant des étoiles, faites simplement:

starred_rows = np.unique(np.where(np.char.endswith(array1, "*") == True)[0])

Pour obtenir les paires d'index, vous pouvez utiliser zip:

np.array(list(zip(*np.where(np.char.endswith(array1, "*") == True))))
1
Serge Ballesta 27 mai 2020 à 13:21

Pour obtenir la sortie idéale mentionnée ci-dessus, vous devez utiliser zip

fil1 = list(zip(*np.where(np.char.endswith(array1, "*") == True)))
print(fil1)  
[(0, 0), (2, 0), (3, 2), (3, 3)] //result

Si vous souhaitez obtenir uniquement l'index des lignes, vous pouvez prendre l'unique du premier élément de votre résultat.

fil1 = list(set(np.where(np.char.endswith(array1, "*") == True)[0]))
print(fil1)
[0, 2, 3]  // result
0
Karthik Radhakrishnan 27 mai 2020 à 13:41
In [81]: array1 = np.array([ 
    ...:        ['*0.70*', '21.59', '4.37', '21.70'], 
    ...:        ['2.15', '21.42', '5.63', '22.33'], 
    ...:        ['*8.00*', '21.17', '5.11', '22.40'], 
    ...:        ['2.36', '22.88', '*2.54*', '*20.95*'], 
    ...:        ['2.07', '22.64', '6.68', '22.26'] 
    ...:        ])                                                                       

Le test char renvoie un tableau booléen:

In [84]: mask = np.char.endswith(array1,"*")                                             
In [85]: mask                                                                            
Out[85]: 
array([[ True, False, False, False],
       [False, False, False, False],
       [ True, False, False, False],
       [False, False,  True,  True],
       [False, False, False, False]])

np.nonzero (aka np.where) trouve les coordonnées des valeurs True, un tableau par dimension:

In [86]: np.nonzero(mask)                                                                
Out[86]: (array([0, 2, 3, 3]), array([0, 0, 2, 3]))

Si vous souhaitez supprimer les lignes, le premier tableau peut être utilisé (le double de 3 ne dérange apparemment pas delete):

In [88]: np.delete(array1, np.nonzero(mask)[0], 0)                                       
Out[88]: 
array([['2.15', '21.42', '5.63', '22.33'],
       ['2.07', '22.64', '6.68', '22.26']], dtype='<U7')

Mais nous pouvons également trouver des lignes avec n'importe quel True avec:

In [89]: mask.any(axis=1)                                                                
Out[89]: array([ True, False,  True,  True, False])

Et utilisez-le pour sélectionner ces lignes (indexation de tableau booléen)

In [91]: array1[mask.any(axis=1)]                                                        
Out[91]: 
array([['*0.70*', '21.59', '4.37', '21.70'],
       ['*8.00*', '21.17', '5.11', '22.40'],
       ['2.36', '22.88', '*2.54*', '*20.95*']], dtype='<U7')

Ou sélectionnez leur not:

In [92]: array1[~mask.any(axis=1)]                                                       
Out[92]: 
array([['2.15', '21.42', '5.63', '22.33'],
       ['2.07', '22.64', '6.68', '22.26']], dtype='<U7')

np.nonzero(Out[89]) est (array([0, 2, 3]),), les lignes de suppression souhaitées.

D'autres réponses ont utilisé la version de liste Python de transpose; numpy's propre transposition fonctionne également:

In [93]: np.argwhere(mask)                                                               
Out[93]: 
array([[0, 0],
       [2, 0],
       [3, 2],
       [3, 3]])
In [94]: np.transpose(np.nonzero(mask))                                                  
Out[94]: 
array([[0, 0],
       [2, 0],
       [3, 2],
       [3, 3]])

Pour supprimer des lignes, cette transposition n'est pas plus utile que le where.

0
hpaulj 27 mai 2020 à 15:02