_______________________________________________
NumPy-Discussion mailing list
NumPy-Di...@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion
For the exactly equal case, how about:
I[1] a = np.array([1,1,1,1])
I[2] np.unique(a).size
O[2] 1 # All equal
I[3] a = np.array([1,1,1,2])
I[4] np.unique(a).size
O[4] 2 # All not equal
> On Mon, Mar 5, 2012 at 11:14 AM, Neal Becker <ndbe...@gmail.com> wrote:
>> What is a simple, efficient way to determine if all elements in an array (in
>> my case, 1D) are equal? How about close?
>
> For the exactly equal case, how about:
>
> I[1] a = np.array([1,1,1,1])
> I[2] np.unique(a).size
> O[2] 1 # All equal
>
> I[3] a = np.array([1,1,1,2])
> I[4] np.unique(a).size
> O[4] 2 # All not equal
I considered this - just not sure if it's the most efficient
Yeah, it is slow:
I[1] a = np.ones(100000)
I[2] timeit np.unique(a).size
1000 loops, best of 3: 1.56 ms per loop
I[3] timeit (a == a[0]).all()
1000 loops, best of 3: 203 us per loop
I think all() short-circuits for bool arrays:
I[4] a[1] = 9
I[5] timeit (a == a[0]).all()
10000 loops, best of 3: 89 us per loop
You could avoid making the bool array by writing a function in cython.
It could grab the first array element and then return False as soon as
it finds an element that is not equal to it. And you could check for
closeness.
Or:
I[8] np.allclose(a, a[0])
O[8] False
I[9] a = np.ones(100000)
I[10] np.allclose(a, a[0])
O[10] True
I[8] np.allclose(a, a[0])
O[8] False
I[9] a = np.ones(100000)
I[10] np.allclose(a, a[0])
O[10] True
How about numpy.ptp, to follow this line? I would expect it's single
pass, but wouldn't short circuit compared to cython of Keith
Josef
>
> -=- Olivier
I[1] a = np.ones(100000)
I[2] timeit (a == a[0]).all()
1000 loops, best of 3: 203 us per loop
I[3] timeit a.min() == a.max()
10000 loops, best of 3: 106 us per loop
I[4] timeit np.ptp(a)
10000 loops, best of 3: 106 us per loop
I[5] a[1] = 9
I[6] timeit (a == a[0]).all()
10000 loops, best of 3: 89.7 us per loop
I[7] timeit a.min() == a.max()
10000 loops, best of 3: 102 us per loop
I[8] timeit np.ptp(a)
10000 loops, best of 3: 103 us per loop
On Mon, Mar 5, 2012 at 11:36 AM, <josef...@gmail.com> wrote:
> How about numpy.ptp, to follow this line? I would expect it's single
> pass, but wouldn't short circuit compared to cython of Keith
I[1] a = np.ones(100000)I[2] timeit (a == a[0]).all()
1000 loops, best of 3: 203 us per loopI[3] timeit a.min() == a.max()
10000 loops, best of 3: 106 us per loop
I[4] timeit np.ptp(a)
10000 loops, best of 3: 106 us per loop
I[5] a[1] = 9
I[6] timeit (a == a[0]).all()
10000 loops, best of 3: 89.7 us per loop
I[7] timeit a.min() == a.max()
10000 loops, best of 3: 102 us per loop
I[8] timeit np.ptp(a)
10000 loops, best of 3: 103 us per loop
Good point.
For fun, here's the speed of a simple cython allclose:
I[2] a = np.ones(100000)
I[3] timeit a.min() == a.max()
10000 loops, best of 3: 106 us per loop
I[4] timeit allequal(a)
10000 loops, best of 3: 68.9 us per loop
I[5] a[1] = 9
I[6] timeit a.min() == a.max()
10000 loops, best of 3: 102 us per loop
I[7] timeit allequal(a)
1000000 loops, best of 3: 269 ns per loop
where
@cython.boundscheck(False)
@cython.wraparound(False)
def allequal(np.ndarray[np.float64_t, ndim=1] a):
cdef:
np.float64_t a0
Py_ssize_t i, n=a.size
a0 = a[0]
for i in range(n):
if a[i] != a0:
return False
return True
Similarly, NaNs or Infs could cause problems: they should signal as
False, but several of the solutions would return True.
~Brett
But doesn't this one fail on empty array?
Yes. I'm optimizing for fun, not for corner cases. This should work
for size zero and NaNs:
@cython.boundscheck(False)
@cython.wraparound(False)
def allequal(np.ndarray[np.float64_t, ndim=1] a):
cdef:
np.float64_t a0
Py_ssize_t i, n=a.size
if n == 0:
return False # Or would you like True?
a0 = a[0]
for i in range(n):
if a[i] != a0:
return False
return True
Sorry for all the posts. I'll go back to being quiet. Seems like
np.allclose returns True for empty arrays:
I[2] a = np.array([])
I[3] np.allclose(np.array([]), np.array([]))
O[3] True
The original allequal cython code did the same:
I[4] allequal(a)
O[4] True