2013-05-02 11 views
63

Mam wiele odległości zwanych dists. Chcę wybrać odległości, które są pomiędzy dwiema wartościami. Napisałem następujący wiersz kodu, aby to zrobić:Numpy, gdzie funkcja wiele warunków

dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))] 

Jednak to wybranie tylko za stan

(np.where(dists <= r + dr)) 

Gdybym wykonać kolejno polecenia za pomocą zmiennej tymczasowej to działa dobrze. Dlaczego powyższy kod nie działa i jak mogę go uruchomić?

Cheers

Odpowiedz

107

Najlepszym sposobem na danym przypadku będzie tylko zmienić swoje dwa kryteria do jednego kryterium:

dists[abs(dists - r - dr/2.) <= dr/2.] 

To tylko tworzy jedną logiczną tablicę, i moim zdaniem jest łatwiejsze przeczytać, ponieważ mówi, jest dist w dr lub r? (Chociaż na nowo zdefiniowałem r jako centrum twojego regionu zainteresowania, a nie na początek, więc r = r + dr/2.) Ale to nie odpowiada na twoje pytanie.


Odpowiedź na zapytanie:
rzeczywistości nie potrzebują where jeśli jesteś po prostu starają się odfiltrować elementy dists które nie pasują kryteria:

dists[(dists >= r) & (dists <= r+dr)] 

Ponieważ & daje elementycznie and (potrzebne są nawiasy).

Lub, jeśli chcesz korzystać z where z jakiegoś powodu, można zrobić:

dists[(np.where((dists >= r) & (dists <= r + dr)))] 

Dlaczego:
Powód to nie działa, ponieważ jest np.where zwraca listę indeksów, a nie tablicy boolowskiej. Próbujesz uzyskać and między dwiema listami liczb, które oczywiście nie mają oczekiwanych wartości. Jeśli wartości a i b są wartościami a and b, to zwraca się . Powiedzenie czegoś takiego, jak [0,1,2] and [2,3,4], po prostu da ci [2,3,4].Oto ona w akcji:

In [230]: dists = np.arange(0,10,.5) 
In [231]: r = 5 
In [232]: dr = 1 

In [233]: np.where(dists >= r) 
Out[233]: (array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),) 

In [234]: np.where(dists <= r+dr) 
Out[234]: (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),) 

In [235]: np.where(dists >= r) and np.where(dists <= r+dr) 
Out[235]: (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),) 

Czego spodziewali się porównać był po prostu logiczna tablicą, na przykład

In [236]: dists >= r 
Out[236]: 
array([False, False, False, False, False, False, False, False, False, 
     False, True, True, True, True, True, True, True, True, 
     True, True], dtype=bool) 

In [237]: dists <= r + dr 
Out[237]: 
array([ True, True, True, True, True, True, True, True, True, 
     True, True, True, True, False, False, False, False, False, 
     False, False], dtype=bool) 

In [238]: (dists >= r) & (dists <= r + dr) 
Out[238]: 
array([False, False, False, False, False, False, False, False, False, 
     False, True, True, True, False, False, False, False, False, 
     False, False], dtype=bool) 

Teraz można zadzwonić np.where na Nomenklaturze logicznej tablicy:

In [239]: np.where((dists >= r) & (dists <= r + dr)) 
Out[239]: (array([10, 11, 12]),) 

In [240]: dists[np.where((dists >= r) & (dists <= r + dr))] 
Out[240]: array([ 5. , 5.5, 6. ]) 

Lub po prostu indeksuj oryginalną tablicę z tablicą boolowską przy użyciu fancy indexing

In [241]: dists[(dists >= r) & (dists <= r + dr)] 
Out[241]: array([ 5. , 5.5, 6. ]) 
0

Ja pracowałem na tym prostym przykładzie

import numpy as np 

ar = np.array([3,4,5,14,2,4,3,7]) 

print [X for X in list(ar) if (X >= 3 and X <= 6)] 

>>> 
[3, 4, 5, 4, 3] 
+5

W tym przypadku nie ma potrzeby powtarzania. NumPy ma indeksowanie boolowskie. – M456

2

Spróbuj:

np.intersect1d(np.where(dists >= r)[0],np.where(dists <= r + dr)[0]) 
16

Ponieważ przyjęta odpowiedź wyjaśnił problem bardzo dobrze. można również użyć numpy logical functions który jest bardziej odpowiedni stan stwardnienia tutaj:

np.where(np.logical_and(np.greater_equal(dists,r),np.greater_equal(dists,r + dr))) 
+2

Ten IMO jest najbardziej czytelną odpowiedzią! –

+1

brakuje ')' na końcu, prawda? – Olivia

+1

@ Olivia Tak, dzięki za przypomnienie;) – Kasramvd

0

Lubię używać np.vectorize do takich zadań. Rozważmy następujący:

>>> # function which returns True when constraints are satisfied. 
>>> func = lambda d: d >= r and d<= (r+dr) 
>>> 
>>> # Apply constraints element-wise to the dists array. 
>>> result = np.vectorize(func)(dists) 
>>> 
>>> result = np.where(result) # Get output. 

Można również użyć np.argwhere zamiast np.where dla jasnego wyjścia. Ale to jest twój telefon :)

Mam nadzieję, że to pomaga.