2014-10-02 12 views
10

Czy w numpy istnieje ładny idiomatyczny sposób sprawdzania, czy wszystkie wiersze są równe w tablicy 2d?Jak sprawdzić, czy wszystkie wiersze są równe w numpy?

mogę zrobić coś podobnego

np.all([np.array_equal(M[0], M[i]) for i in xrange(1,len(M))]) 

to wydaje się mieszać z listy python numpy tablice który jest brzydki i przypuszczalnie również powolny.

Czy jest ładniejszy/schludniejszy sposób?

+1

Jak już powiedziałem na [podobne pytanie] (http://stackoverflow.com/q/14859458/2988730), to naprawdę potrzebuje właściwego rozwiązania, które nie tworzy tymczasowej tablicy tak dużej, jak oryginał (który zarówno odpowiedzi tutaj tak samo jak i tam). Opublikuję odpowiedź po dodaniu numpy. –

Odpowiedz

11

Jednym ze sposobów jest odejmij pierwszy wiersz ze wszystkich wierszy macierzy i sprawdzić, że każda pozycja jest równa 0:

>>> a = np.arange(9).reshape(3, 3) 
>>> b = np.ones((3, 3)) 
>>> ((a - a[0]) == 0).all() 
False 
>>> ((b - b[0]) == 0).all() 
True 

to może być szybsze niż identyfikowanie unikalnych wierszy dla większych tablic becaus e pozwala uniknąć dużej liczby potrzebnych porównań.

Nieco szybszy sposób stosując tę ​​samą podstawową ideą jest:

(arr == arr[0]).all() 

to sprawdzenie, że każdy rząd arr wynosi pierwszym rzędzie arr.

+0

Myślę, że to najszybszy sposób. Dziękuję Ci. – eleanora

+2

Sprawdzanie równości zamiast równości 0 różnicy jest prawdopodobnie odrobinę szybsze. – Jaime

+0

Co na temat '(np.diff (b, 1, 1) == 0) .all()' – farenorth

5

Wystarczy sprawdzić, czy liczba, jeśli unikatowe elementy w tablicy są 1:

>>> arr = np.array([[1]*10 for _ in xrange(5)]) 
>>> len(np.unique(arr)) == 1 
True 

Rozwiązanie wzorowane unutbu na answer:

>>> arr = np.array([[1]*10 for _ in xrange(5)]) 
>>> np.all(np.all(arr == arr[0,:], axis = 1)) 
True 

Jeden problem z kodem polega na tym, że najpierw tworzysz całą listę, zanim nałożysz na nią np.all(). Dzięki temu nie ma zwarcie dzieje się w Twojej wersji, zamiast, że byłoby lepiej, gdyby użyć Pythona all() z wyrażeniem generatora:

rozrządu porównań:

>>> M = arr = np.array([[3]*100] + [[2]*100 for _ in xrange(1000)]) 
>>> %timeit np.all(np.all(arr == arr[0,:], axis = 1)) 
1000 loops, best of 3: 272 µs per loop 
>>> %timeit (np.diff(M, axis=0) == 0).all() 
1000 loops, best of 3: 596 µs per loop 
>>> %timeit np.all([np.array_equal(M[0], M[i]) for i in xrange(1,len(M))]) 
100 loops, best of 3: 10.6 ms per loop 
>>> %timeit all(np.array_equal(M[0], M[i]) for i in xrange(1,len(M))) 
100000 loops, best of 3: 11.3 µs per loop 

>>> M = arr = np.array([[2]*100 for _ in xrange(1000)]) 
>>> %timeit np.all(np.all(arr == arr[0,:], axis = 1)) 
1000 loops, best of 3: 330 µs per loop 
>>> %timeit (np.diff(M, axis=0) == 0).all() 
1000 loops, best of 3: 594 µs per loop 
>>> %timeit np.all([np.array_equal(M[0], M[i]) for i in xrange(1,len(M))]) 
100 loops, best of 3: 9.51 ms per loop 
>>> %timeit all(np.array_equal(M[0], M[i]) for i in xrange(1,len(M))) 
100 loops, best of 3: 9.44 ms per loop 
+0

Myślę, że odpowiedź Ajcr jest jeszcze szybsza! – eleanora

+2

@ user2179021 W systemie bierze '650 μs', więc wolniej niż moja druga odpowiedź. –

+0

Uzgodnione - druga metoda jest szybsza niż moja w moim systemie. –

Powiązane problemy