What are the rules for comparing numpy arrays using ==?
Asked Answered
M

3

9

For example, trying to make sense of these results:

>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> (x == np.array([[1],[2]])).astype(np.float32)
array([[ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]], dtype=float32)
>>> (x == np.array([1,2]))
   False
>>> (x == np.array([[1]])).astype(np.float32)
array([[ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]], dtype=float32)
>>> (x == np.array([1])).astype(np.float32)
array([ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.], dtype=float32)

>>> (x == np.array([[1,3],[2]]))
False
>>> 

What's going on here? In the case of [1], it's comparing 1 to each element of x and aggregating the result in an array. In the case of [[1]], same thing. It's easy to figure out what's going to occur for specific array shapes by just experimenting on the repl. But what are the underlying rules where both sides can have arbitrary shapes?

Mufti answered 14/2, 2016 at 20:47 Comment(1)
Ppl should ask questions like yalis. With good, exhaustive examples.Heifetz
M
6

NumPy tries to broadcast the two arrays to compatible shapes before comparison. If the broadcasting fails, False is currently returned. In the future,

The equality operator == will in the future raise errors like np.equal if broadcasting or element comparisons, etc. fails.

Otherwise, a boolean array resulting from the element-by-element comparison is returned. For example, since x and np.array([1]) are broadcastable, an array of shape (10,) is returned:

In [49]: np.broadcast(x, np.array([1])).shape
Out[49]: (10,)

Since x and np.array([[1,3],[2]]) are not broadcastable, False is returned by x == np.array([[1,3],[2]]).

In [50]: np.broadcast(x, np.array([[1,3],[2]])).shape
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-50-56e4868cd7f7> in <module>()
----> 1 np.broadcast(x, np.array([[1,3],[2]])).shape

ValueError: shape mismatch: objects cannot be broadcast to a single shape
Moriyama answered 14/2, 2016 at 20:54 Comment(1)
It's worth noting that, as documented in this question, as of 1.14.1 the deprecated behavior still hasn't been removed. So presumably, until some point even farther in the future, you need to be careful to call np.equal instead of == if there seems to be a realistic chance of a MemoryError.Farming
C
3

It's possible that what's confusing you is that:

  1. some broadcasting is going on.

  2. you appear to have an older version of numpy.


x == np.array([[1],[2]])

is broadcasting. It compares x to each of the first and second arrays; as they are scalars, broadcasting implies that it compares each element of x to each of the scalars.


However, each of

x == np.array([1,2])

and

x == np.array([[1,3],[2]])

can't be broadcast. By me, with numpy 1.10.4, this gives

/usr/local/bin/ipython:1: DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.
#!/usr/bin/python
False
Carmelo answered 14/2, 2016 at 20:55 Comment(0)
H
0

Adding to unutbu's answer, arrays do not need to have the same number of dimensions. For example, dimensions with size 1 are stretched to match the other.

A      (4d array):  8 x 1 x 6 x 1
B      (3d array):      7 x 1 x 5
Result (4d array):  8 x 7 x 6 x 5

A      (2d array):  5 x 4
B      (1d array):      1
Result (2d array):  5 x 4

A      (2d array):  5 x 4
B      (1d array):      4
Result (2d array):  5 x 4

A      (3d array):  15 x 3 x 5
B      (3d array):  15 x 1 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 1
Result (3d array):  15 x 3 x 5
Heifetz answered 9/8, 2020 at 19:45 Comment(1)
What comparisons do these represent? How do A and B related to the result? Just kinda confused what the pattern is.Agreement

© 2022 - 2024 — McMap. All rights reserved.