2012-03-05 12 views
26

Mam tablicę liczb NumPy. Chcę policzyć, ile z tych wartości znajduje się w określonym zakresie, powiedzmy: x < 100 i x> 25. Przeczytałem o liczniku, ale wydaje się, że jest on ważny tylko dla wartości specjalnych, a nie zakresów wartości. Szukałem, ale nie znalazłem nic dotyczącego mojego konkretnego problemu. Jeśli ktoś mógłby wskazać mi właściwą dokumentację, byłbym wdzięczny. DziękujęJak liczyć wartości w pewnym zakresie w tablicy Numpy?

Próbowałem to

X = array(X) 
    for X in range(25, 100): 
     print(X) 

Ale to właśnie daje mi numery między 25 a 99.

EDIT Dane używam został stworzony przez inny program. Następnie użyłem skryptu do odczytania danych i zapisania ich jako listy. Następnie wziąłem listę i włączyłem ją do tablicy używając tablicy (r).

Edit

Wynikiem działania

>>> a[0:10] 
array(['29.63827346', '40.61488812', '25.48300065', '26.22910525', 
    '42.41172923', '20.15013315', '34.95323355', '13.03604098', 
    '29.71097606', '9.53222141'], 
    dtype='<U11') 
+0

@Senderle, które zrobiły to dziękuję bardzo !! Próbowałem metody Svena po rekonwersji tablicy i działało idealnie! Jeszcze raz dziękuję – Surfcast23

Odpowiedz

48

Jeśli tablica jest nazywany a, liczbę elementów spełniających 25 < x < 100 jest

((25 < a) & (a < 100)).sum() 

wyrażenie (25 < a) & (a < 100) wyniki w Boolean tablica o tym samym kształcie, co a z wartość True dla wszystkich elementów, które spełniają warunek. Podsumowanie tej tablicy Boolean traktuje wartości True jako wartości 1 i jako 0.

+1

@SvenI spróbowałem twojej metody, ale dostałem ten błąd '' TypeError: unorderable types: int() Surfcast23

+1

@ Surfcast23: [Działa dla mnie.] (Https: //gist.github. com/1975690) Jakiej wersji NumPy i Python używasz? –

+0

Używam Pythona 3.2 – Surfcast23

6

Można użyć histogram. Oto prosty przykład użycia:

>>> import numpy 
>>> a = numpy.random.random(size=100) * 100 
>>> numpy.histogram(a, bins=(0.0, 7.3, 22.4, 55.5, 77, 79, 98, 100)) 
(array([ 8, 14, 34, 31, 0, 12, 1]), 
array([ 0. , 7.3, 22.4, 55.5, 77. , 79. , 98. , 100. ])) 

w danym przypadku będzie to wyglądać mniej więcej tak:

>>> numpy.histogram(a, bins=(25, 100)) 
(array([73]), array([ 25, 100])) 

Dodatkowo, gdy masz listę ciągów, trzeba wyraźnie określić rodzaj, tak, że numpy wie, aby utworzyć tablicę zmiennych zamiast listy łańcuchów.

>>> strings = [str(i) for i in range(10)] 
>>> numpy.array(strings) 
array(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], 
     dtype='|S1') 
>>> numpy.array(strings, dtype=float) 
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) 
+0

Spróbuję dzięki! – Surfcast23

+0

@ Surfcast23, tak, ten jest bardziej ogólny, ale jeśli naprawdę potrzebujesz tylko jednego pojemnika, [Sven] (http://stackoverflow.com/a/9560228/577088) będzie szybszy. – senderle

+0

Uruchomiłem kod i otrzymałem '' (array ([- 481], dtype = int32), array ([25, 100])) "Co mnie niepokoi, to znak ujemny, jak powinienem go interpretować? – Surfcast23

3

odpowiedź Svena jest sposobem, aby to zrobić, jeśli nie chcą kolejnych wartości dopasowywania procesów.
Poniższe dwa przykłady powrotu kopii tylko wartości dopasowania:

np.compress((25 < a) & (a < 100), a).size 

A:

a[(25 < a) & (a < 100)].size 

Przykład interpretera sesja

>>> import numpy as np 
>>> a = np.random.randint(200,size=100) 
>>> a 
array([194, 131, 10, 100, 199, 123, 36, 14, 52, 195, 114, 181, 138, 
     144, 70, 185, 127, 52, 41, 126, 159, 39, 68, 118, 124, 119, 
     45, 161, 66, 29, 179, 194, 145, 163, 190, 150, 186, 25, 61, 
     187, 0, 69, 87, 20, 192, 18, 147, 53, 40, 113, 193, 178, 
     104, 170, 133, 69, 61, 48, 84, 121, 13, 49, 11, 29, 136, 
     141, 64, 22, 111, 162, 107, 33, 130, 11, 22, 167, 157, 99, 
     59, 12, 70, 154, 44, 45, 110, 180, 116, 56, 136, 54, 139, 
     26, 77, 128, 55, 143, 133, 137, 3, 83]) 
>>> np.compress((25 < a) & (a < 100),a).size 
34 
>>> a[(25 < a) & (a < 100)].size 
34 

powyższych przykładach użyć „bitową i "(&) do obliczeń elementarnych wzdłuż dwóch tablic boolowskich, które tworzy się dla celów porównawczych.
Innym sposobem napisać doskonałą odpowiedź Svena, na przykład, jest:

np.bitwise_and(25 < a, a < 100).sum() 

Boolean tablice zawierają True wartości podczas meczów stanie i False, gdy tak nie jest.
Bonus aspekt wartości logicznych jest True jest równoważna 1 i False 0.

+0

@Sevn i Adam, jestem jeszcze całkiem nowy, python ~ 6 miesięcy nie bardzo konsekwentnie choć. Czy możecie wyjaśnić, jak i dlaczego działają wasze skrypty? Dziękuję – Surfcast23

+0

Albo wskaż mi, gdzie mogę to przeczytać. – Surfcast23

+0

@ Surfcast23: Dodałem trochę wyjaśnienia. Tak trzymać! – bernie

2

myślę @Sven Marnach odpowiedź jest dość miły, ponieważ działa na tablicy numpy samego, który będzie szybki i efektywny (Implementacja C).

chciałbym umieścić test pod jednym warunkiem jak 25 < x < 100, więc to pewnie zrobić to tak:

len([x for x in a.ravel() if 25 < x < 100])

+1

Nice. Aby użyć wyrażenia gen-expr: 'sum (1 for i in a.ravel() if 25 bernie

+0

to też jest dobre. na początku próbowałem użyć 'len()' na generatorze i ku mojemu zdziwieniu nie działa – wim

+0

@wim: 'len()' nie działa z wyrażeń generatora, ponieważ iteratory zwykle nie mają skończonej długości. Dlatego podejście 'sum (1 ...)' jest lepsze: ma stały i dużo mniejszy ślad pamięci, ponieważ nie trzeba tworzyć listy pośredniej. – EOL

5

Opierając się na dobrym podejściem Svena, można również wykonać bardziej bezpośredni:

numpy.count_nonzero((25 < a) & (a < 100)) 

Ten pierwszy tworzy tablicę wartości logiczne z jedną logiczną dla każdego numeru wejściowego w tablicy a, a następnie policzyć non-fAŁSZ (czyli wartości (prawda), który daje numbe r pasujących liczb).

Należy jednak zauważyć, że podejście to jest dwa razy wolniejsze niż podejście Svena o numerze .sum(), w przypadku tablicy o liczbach 100 000 (NumPy 1.6.1, Python 2.7.3) - o około 300 μs względem 150 μs.

Powiązane problemy