Comparison & Logical Operations
Compare arrays element by element (==, !=, >, <), combine results with logical_and/or/not, and summarise with any, all and array_equal.
"In which matches did Virat outscore Rohit?", "Did anyone get a duck?", "Is this season's scorecard identical to the backup copy?" — these are yes/no questions asked for every element. NumPy answers them with comparison operators (which give boolean arrays) and logical functions (which combine or summarise them).
Definition
A comparison operation (
==,!=,>,>=,<,<=) compares arrays element-wise and returns a boolean array of the same shape. Logical operations (np.logical_and,np.logical_or,np.logical_not,np.logical_xor— or the operators&,|,~,^) combine boolean arrays element-wise.any/allreduce a boolean array to a single answer (or one answer per row/column), andnp.array_equaltells you whether two whole arrays are identical.
- Boolean array — each element is
TrueorFalse; dtypebool. It can be used as a mask, counted with.sum(), or averaged with.mean()(= fraction of True). - Element-wise logical —
np.logical_and(a, b)is True only where both are True at that position. - Reduce —
any= "at least one True?",all= "every element True?".
Syntax
python
a == b a != b a > b a >= b a < b a <= b # b: scalar or array
np.logical_and(c1, c2) # same as c1 & c2
np.logical_or(c1, c2) # same as c1 | c2
np.logical_not(c1) # same as ~c1
np.logical_xor(c1, c2) # same as c1 ^ c2 (exactly one True)
np.any(c, axis=None) # or c.any()
np.all(c, axis=None) # or c.all()
np.array_equal(a, b) # True if same shape AND same elements
np.allclose(a, b) # True if equal within a small tolerance (floats)| Function | Parameters | Returns | Default |
|---|---|---|---|
np.logical_and/or/xor(x1, x2) | two boolean (or truthy) arrays | boolean array | — |
np.logical_not(x) | one array | boolean array | — |
np.any(a, axis) | array, optional axis | bool, or bool array per axis | axis=None (whole array) |
np.all(a, axis) | array, optional axis | bool, or bool array per axis | axis=None |
np.array_equal(a1, a2) | two arrays | one bool | equal_nan=False |
np.allclose(a, b, rtol, atol) | two arrays, tolerances | one bool | rtol=1e-05, atol=1e-08 |
Example — comparisons give boolean arrays
python
import numpy as np
virat = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
rohit = np.array([56, 0, 74, 88, 32, 45, 61, 17, 90, 38, 72, 5, 83, 49])
virat_more = virat > rohit
print("virat > rohit:", virat_more)
print("dtype :", virat_more.dtype)
print("Matches Virat won :", virat_more.sum())
print("Fraction won :", virat_more.mean().round(2))
print("Same score? :", (virat == rohit).any())
print("Virat >= 50 :", virat >= 50)text
virat > rohit: [ True True True False True False True True False True False True
False True]
dtype : bool
Matches Virat won : 9
Fraction won : 0.64
Same score? : False
Virat >= 50 : [ True False True False True False True True False True False True
False True]How it works: comparing two arrays of the same shape gives one True/False per match. Because True counts as 1, .sum() counts the wins and .mean() gives the fraction.
Example — logical_and, logical_or, logical_not
python
virat = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
rohit = np.array([56, 0, 74, 88, 32, 45, 61, 17, 90, 38, 72, 5, 83, 49])
both_50 = np.logical_and(virat >= 50, rohit >= 50)
either_duck = np.logical_or(virat == 0, rohit == 0)
virat_not_50 = np.logical_not(virat >= 50)
only_one_50 = np.logical_xor(virat >= 50, rohit >= 50)
print("Both 50+ :", np.where(both_50)[0] + 1)
print("Either a duck :", np.where(either_duck)[0] + 1)
print("Virat below 50:", virat_not_50.sum(), "matches")
print("Exactly one 50+:", only_one_50.sum(), "matches")
print("Same as & ? :", np.array_equal(both_50, (virat >= 50) & (rohit >= 50)))text
Both 50+ : [1 3 7]
Either a duck : [2 6]
Virat below 50: 6 matches
Exactly one 50+: 9 matches
Same as & ? : TrueHow it works: the np.logical_* functions and the operators &, |, ~, ^ give identical results on boolean arrays. The functions are easier to read and don't need extra parentheses; the operators are shorter. The match numbers come from np.where(...)[0] + 1.
Example — any and all (with axis)
python
runs = np.array([
[72, 45, 88, 31, 64, 0], # Virat
[56, 0, 74, 88, 32, 45], # Rohit
[45, 32, 0, 67, 18, 54], # Hardik
])
balls = np.array([
[48, 32, 55, 24, 41, 0],
[39, 0, 50, 56, 25, 33],
[31, 24, 0, 46, 15, 38],
])
print("Any duck in the table? :", np.any(runs == 0))
print("All scores below 100? :", np.all(runs < 100))
print("Duck per player (axis=1) :", (runs == 0).any(axis=1))
print("All players 30+ (axis=0) :", (runs >= 30).all(axis=0))text
Any duck in the table? : True
All scores below 100? : True
Duck per player (axis=1) : [ True True True]
All players 30+ (axis=0) : [ True False False True False False]How it works: without axis, any/all look at the whole array and return one bool. With axis=1 you get one answer per row (per player); with axis=0, one answer per column (per match).
Example — comparing whole arrays
python
a = np.array([72, 45, 88])
b = np.array([72, 45, 88])
c = np.array([72, 45, 89])
print("a == b :", a == b)
print("array_equal(a, b) :", np.array_equal(a, b))
print("array_equal(a, c) :", np.array_equal(a, c))
print("array_equal(a, a[:2]):", np.array_equal(a, a[:2]))
x = np.array([0.1 + 0.2])
print("x == 0.3 :", x == 0.3)
print("allclose(x, 0.3) :", np.allclose(x, 0.3))text
a == b : [ True True True]
array_equal(a, b) : True
array_equal(a, c) : False
array_equal(a, a[:2]): False
x == 0.3 : [False]
allclose(x, 0.3) : TrueHow it works: a == b gives an array of answers; np.array_equal gives one answer and also returns False if the shapes differ. Floats are stored in binary, so 0.1 + 0.2 is 0.30000000000000004; use np.allclose to compare floats with a tolerance.
Example — never use if on a whole boolean array
python
virat = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
rohit = np.array([56, 0, 74, 88, 32, 45, 61, 17, 90, 38, 72, 5, 83, 49])
try:
if virat > 50:
print("big scores")
except ValueError as e:
print("ValueError:", e)
if (virat > 50).any():
print("At least one score above 50")
if not (virat > 0).all():
print("Not every score is above 0 (there is a duck)")text
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
At least one score above 50
Not every score is above 0 (there is a duck)Comparison — operators vs functions vs Python keywords
| Python keyword (single values) | NumPy operator (arrays) | NumPy function |
|---|---|---|
and | & | np.logical_and |
or | | | np.logical_or |
not | ~ | np.logical_not |
| — | ^ | np.logical_xor |
if any(...) | — | np.any / .any() |
if all(...) | — | np.all / .all() |
Common mistakes
- ❌
if arr == other:→ ambiguous truth value. ✅if np.array_equal(arr, other):. - ❌
(a > 1) and (b > 1)with arrays. ✅np.logical_and(a > 1, b > 1)or(a > 1) & (b > 1). - ❌
a > 30 & a < 60without parentheses. ✅(a > 30) & (a < 60). - ❌ Comparing floats with
==. ✅np.allclose/np.isclose. - ❌ Using
~on an int array expecting "not" — on ints~is bitwise NOT (~5 == -6). ✅ Use it only on boolean arrays, or usenp.logical_not.
Interview tip
Q: Difference between a == b and np.array_equal(a, b)?
A: a == b compares element-wise and returns a boolean array (and may broadcast). np.array_equal returns a single True only if both arrays have the same shape and all elements are equal — use it in if statements and tests.
Key points to remember
- Comparison operators (==, !=, >, >=, <, <=) work element-wise and return a boolean array of the same shape.
- boolean.sum() counts True values; boolean.mean() gives the fraction that is True.
- np.logical_and / logical_or / logical_not / logical_xor combine conditions element-wise (same as & | ~ ^).
- np.any asks 'at least one True?', np.all asks 'all True?'; pass axis to get one answer per row or column.
- np.array_equal(a, b) returns one bool: True only if shapes AND all elements match.
- Use np.allclose (not ==) to compare floating-point arrays.
- Never write if arr > x: on an array — use .any() or .all().
Try it yourself
Who scored more, match by match?
Logical functions and any/all
array_equal vs ==
Practice: consistent players
Revision Flashcards
Tap a card to flip it and see the answer.
