Supposons que j'ai un tableau numpy x = [5, 2, 3, 1, 4, 5]
, y = ['f', 'o', 'o', 'b', 'a', 'r']
. Je souhaite sélectionner les éléments dans y
correspondant aux éléments de x
qui sont supérieurs à 1 et inférieurs à 5.
J'ai essayé
x = array([5, 2, 3, 1, 4, 5])
y = array(['f','o','o','b','a','r'])
output = y[x > 1 & x < 5] # desired output is ['o','o','a']
mais ça ne marche pas. Comment je ferais ça?
Votre expression fonctionne si vous ajoutez des parenthèses:
>>> y[(1 < x) & (x < 5)]
array(['o', 'o', 'a'],
dtype='|S1')
IMO OP ne veut pas réellement np.bitwise_and()
(alias &
) mais veut réellement np.logical_and()
car ils comparent des valeurs logiques telles que True
et False
- voir ce SO post sur logique vs bit pour voir la différence.
>>> x = array([5, 2, 3, 1, 4, 5])
>>> y = array(['f','o','o','b','a','r'])
>>> output = y[np.logical_and(x > 1, x < 5)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
dtype='|S1')
Et la manière équivalente de le faire est avec np.all()
en définissant correctement l’argument axis
.
>>> output = y[np.all([x > 1, x < 5], axis=0)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
dtype='|S1')
en chiffres:
>>> %timeit (a < b) & (b < c)
The slowest run took 32.97 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.15 µs per loop
>>> %timeit np.logical_and(a < b, b < c)
The slowest run took 32.59 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.17 µs per loop
>>> %timeit np.all([a < b, b < c], 0)
The slowest run took 67.47 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.06 µs per loop
si utiliser np.all()
est plus lent, mais &
et logical_and
sont à peu près les mêmes.
Ajouter un détail à @ J.F. Réponses de Sebastian et @Mark Mikofski:
Si on veut obtenir les index correspondants (plutôt que les valeurs réelles du tableau), le code suivant fera:
Pour satisfaire plusieurs (toutes) conditions:
select_indices = np.where( np.logical_and( x > 1, x < 5) )[0] # 1 < x <5
Pour satisfaire plusieurs (ou) conditions:
select_indices = np.where( np.logical_or( x < 1, x > 5 ) )[0] # x <1 or x >5
J'aime utiliser np.vectorize
pour de telles tâches. Considérer ce qui suit:
>>> # Arrays
>>> x = np.array([5, 2, 3, 1, 4, 5])
>>> y = np.array(['f','o','o','b','a','r'])
>>> # Function containing the constraints
>>> func = np.vectorize(lambda t: t>1 and t<5)
>>> # Call function on x
>>> y[func(x)]
>>> array(['o', 'o', 'a'], dtype='<U1')
L'avantage est que vous pouvez ajouter beaucoup plus de types de contraintes dans la fonction vectorisée.
J'espère que ça aide.
En fait, je le ferais de cette façon:
L1 est la liste d'index des éléments satisfaisant la condition 1. Vous pouvez peut-être utiliser somelist.index(condition1)
ou np.where(condition1)
pour obtenir L1.
De même, vous obtenez L2, une liste d'éléments satisfaisant la condition 2;
Ensuite, vous trouvez l'intersection à l'aide de intersect(L1,L2)
.
Vous pouvez également trouver l'intersection de plusieurs listes si vous devez satisfaire à plusieurs conditions.
Ensuite, vous pouvez appliquer un index à n’importe quel autre tableau, par exemple x.
Pour les tableaux 2D, vous pouvez le faire. Créez un masque 2D en utilisant la condition. Convertissez le masque de condition en int ou en float, selon le tableau, et multipliez-le par le tableau d'origine.
In [8]: arr
Out[8]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.]])
In [9]: arr*(arr % 2 == 0).astype(np.int)
Out[9]:
array([[ 0., 2., 0., 4., 0.],
[ 6., 0., 8., 0., 10.]])