Boolean & Fancy Indexing

Boolean indexing selects array elements by a True/False condition, while fancy indexing selects them by an array of integer positions — together they let you filter and gather data without writing a single loop.

Learn Boolean & Fancy Indexing in our free NumPy course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Numpy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll build boolean masks, filter with conditions, combine tests with & and | , overwrite values that match a rule, and grab arbitrary elements with integer index arrays.

A comparison like arr > 5 doesn't return a single answer — it compares every element and returns a boolean mask : an array of True / False the same shape as the original. That mask is the foundation of filtering, where each True marks a position you want to keep.

Expected output: [False True False True False True] and (6,) .

Put the mask inside the brackets — arr[arr > 5] — and NumPy returns only the elements where the mask is True . This is the single most common way to filter data in NumPy, and the result is always a 1D copy of the matching values.

To combine two tests, use & for "and" and | for "or". Wrap each comparison in parentheses — these operators bind tighter than > or < , so without parentheses NumPy reads the expression wrong and errors out.

A mask can sit on the left of an assignment too. arr[arr < 0] = 0 finds every negative value and replaces it with zero in place — a clean way to clip or clean data.

Expected output: [0 5 0 8 0 2] then [0 5 0 6 0 2] .

Fancy indexing uses a list or array of positions to pick elements in any order: arr[[0, 2, 4]] . It also works on 2D arrays — pass an array of row indices and an array of column indices to gather specific cells.

Expected output: [10 30 50] , [50 10 20] , and [2 7] .

Replace each ___ so the program filters, combines conditions, and uses fancy indexing.

Expected output: [ 9 11] , [4 6] , [ 2 11] . (Answers: > , & , 0 .)

❌ ValueError: The truth value of an array with more than one element is ambiguous

You combined conditions with and / or instead of the bitwise operators.

✅ Fix: use & and | — for example (arr > 2) & (arr < 9) .

❌ Wrong results when combining two conditions

You left out the parentheses, so & ran before the comparisons.

✅ Fix: wrap each test: (arr > 2) & (arr < 9) , never arr > 2 & arr < 9 .

A sensor reports some impossible negative readings. Clip them to zero, then count how many readings are above 50.

Lesson 7 complete — you can filter like a pro!

You now build boolean masks, filter with conditions, combine tests with & and | (always in parentheses), overwrite matching values, and gather arbitrary elements with fancy integer indexing.

🚀 Up next: Reshaping and Flattening — change an array's shape without touching its data.

Practice quiz

What does arr > 5 return for a NumPy array?

  • A single True or False
  • A boolean mask of True/False values
  • The elements greater than 5
  • The count of large elements

Answer: A boolean mask of True/False values. A comparison returns a boolean mask the same shape as the array.

For arr = [3, 8, 1, 10, 5, 7], what is arr[arr > 5]?

Boolean indexing keeps only the elements where the mask is True.

For arr = [3, 8, 1, 10, 5, 7], what is arr[arr % 2 == 0]?

The mask keeps the even numbers: 8 and 10.

How do you combine two array conditions for AND?

  • (a) & (b)
  • a and b
  • a && b
  • and(a, b)

Answer: (a) & (b). Use the bitwise & with each comparison in parentheses.

Why must each comparison be wrapped in parentheses with & and |?

  • To make it run faster
  • Because & binds tighter than the comparison operators
  • Because NumPy requires tuples
  • Parentheses are optional

Answer: Because & binds tighter than the comparison operators. & and | bind tighter than > or <, so parentheses force the comparisons first.

For arr = [3, 8, 1, 10, 5, 7], what is arr[(arr > 2) & (arr < 9)]?

Elements that are both > 2 and < 9 are 3, 8, 5, and 7.

What does arr[arr < 0] = 0 do?

  • Returns a new copy of arr
  • Raises an error
  • Deletes negative values
  • Replaces every negative value with 0 in place

Answer: Replaces every negative value with 0 in place. Assigning through a mask overwrites the matching positions in place.

For arr = [10, 20, 30, 40, 50], what is arr[[4, 0, 1]]?

Fancy indexing returns elements in the exact order of the index list.

For grid = [[1,2,3],[4,5,6],[7,8,9]], what is grid[[0, 2], [1, 0]]?

It pairs (0,1) and (2,0), giving grid[0,1]=2 and grid[2,0]=7.

Do boolean indexing and fancy indexing return a copy or a view?

  • A view that shares memory
  • It depends on dtype
  • A new copy of the data
  • Neither; they error

Answer: A new copy of the data. Both boolean and fancy indexing always return a new copy.