NumPy
Python
Boolean Array
Array Operations
Data Science

How to count the number of true elements in a NumPy bool array

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Counting True values in a NumPy boolean array is a common operation in data filtering, masking, and statistical analysis. The three main approaches are np.sum(arr) (treats True as 1), np.count_nonzero(arr) (counts non-False elements), and arr.sum(). All three are vectorized and fast, but np.count_nonzero is the most semantically clear and slightly faster because it is optimized for counting without performing full summation.

Using np.sum()

python
1import numpy as np
2
3arr = np.array([True, False, True, True, False, True])
4
5# True = 1, False = 0, so sum gives the count of True
6count = np.sum(arr)
7print(count)  # 4
8
9# Equivalent method call on the array
10count = arr.sum()
11print(count)  # 4

NumPy treats True as 1 and False as 0 in arithmetic operations. Summing a boolean array adds up all the 1 values, giving the count of True elements.

Using np.count_nonzero()

python
1arr = np.array([True, False, True, True, False, True])
2
3count = np.count_nonzero(arr)
4print(count)  # 4
5
6# Works on any array — counts elements that are not zero/False
7numbers = np.array([0, 1, 0, 3, 0, 5])
8print(np.count_nonzero(numbers))  # 3

count_nonzero is the most explicit and performant choice for boolean arrays. It does not compute a sum — it simply counts non-zero entries, which is faster for large arrays.

Counting Along an Axis

python
1# 2D boolean array
2matrix = np.array([
3    [True, False, True],
4    [False, False, True],
5    [True, True, True],
6])
7
8# Count True per column (axis=0)
9print(np.sum(matrix, axis=0))  # [2, 1, 3]
10
11# Count True per row (axis=1)
12print(np.sum(matrix, axis=1))  # [2, 1, 3]
13
14# Total count
15print(np.sum(matrix))  # 6
16
17# count_nonzero also supports axis
18print(np.count_nonzero(matrix, axis=0))  # [2, 1, 3]
19print(np.count_nonzero(matrix, axis=1))  # [2, 1, 3]

Both np.sum and np.count_nonzero accept an axis parameter for counting along rows or columns.

Counting with Conditions

python
1data = np.array([15, 22, 8, 42, 30, 5, 18])
2
3# Count elements greater than 10
4count_gt_10 = np.sum(data > 10)
5print(count_gt_10)  # 5
6
7# Count elements in a range
8count_in_range = np.count_nonzero((data >= 10) & (data <= 30))
9print(count_in_range)  # 4
10
11# Count NaN values
12float_data = np.array([1.0, np.nan, 3.0, np.nan, 5.0])
13nan_count = np.sum(np.isnan(float_data))
14print(nan_count)  # 2
15
16# Count non-NaN values
17valid_count = np.count_nonzero(~np.isnan(float_data))
18print(valid_count)  # 3

Comparison operators on NumPy arrays return boolean arrays, which can be summed or counted directly. Use & (and), | (or), ~ (not) for combining conditions.

Performance Comparison

python
1import numpy as np
2import timeit
3
4large_arr = np.random.choice([True, False], size=10_000_000)
5
6# np.count_nonzero — fastest
7t1 = timeit.timeit(lambda: np.count_nonzero(large_arr), number=100)
8
9# np.sum — slightly slower (computes actual sum)
10t2 = timeit.timeit(lambda: np.sum(large_arr), number=100)
11
12# Python's built-in sum — much slower (no vectorization)
13t3 = timeit.timeit(lambda: sum(large_arr), number=10)
14
15print(f"count_nonzero: {t1:.3f}s")  # ~0.3s
16print(f"np.sum:        {t2:.3f}s")  # ~0.5s
17print(f"Python sum:    {t3:.3f}s")  # ~5.0s (10x runs)

count_nonzero is faster than sum because it does not accumulate values — it only increments a counter. Python's built-in sum() iterates element-by-element and is 10-100x slower.

Counting False Elements

python
1arr = np.array([True, False, True, True, False, True])
2
3# Count False values
4false_count = np.sum(~arr)  # Invert, then count True
5print(false_count)  # 2
6
7# Or subtract from total length
8false_count = len(arr) - np.sum(arr)
9print(false_count)  # 2
10
11# Or count zeros
12false_count = np.count_nonzero(arr == False)
13print(false_count)  # 2

With Pandas

python
1import pandas as pd
2
3s = pd.Series([True, False, True, True, False])
4
5# Count True
6print(s.sum())  # 3
7
8# Count False
9print((~s).sum())  # 2
10
11# With conditions on a DataFrame
12df = pd.DataFrame({'score': [85, 92, 67, 45, 78]})
13passing = (df['score'] >= 70).sum()
14print(f"Passing: {passing}")  # 3

Pandas Series and DataFrame columns support the same boolean counting patterns as NumPy arrays.

Common Pitfalls

  • Using Python's built-in sum(): sum(numpy_array) works but is 10-100x slower than np.sum() because it iterates element-by-element instead of using vectorized operations.
  • Confusing count_nonzero with non-boolean arrays: np.count_nonzero([0, 1, 2, 3]) returns 3 (counts all non-zero), not 1. For boolean arrays this is correct, but for numeric arrays the semantics differ.
  • Using & instead of and for conditions: NumPy conditions must use & (bitwise AND), not and (logical AND). (arr > 5) and (arr < 10) raises ValueError. Use (arr > 5) & (arr < 10).
  • Forgetting parentheses in compound conditions: arr > 5 & arr < 10 is parsed as arr > (5 & arr) < 10 due to operator precedence. Always wrap conditions in parentheses: (arr > 5) & (arr < 10).
  • Counting on a non-boolean array expecting True/False: np.sum(arr) on an integer array computes the arithmetic sum, not a count. First create a boolean mask: np.sum(arr > 0).

Summary

  • np.count_nonzero(arr) is the fastest and most semantically clear method for counting True values
  • np.sum(arr) works because True = 1 and False = 0 in NumPy arithmetic
  • Both support axis parameter for row-wise or column-wise counting
  • Use comparison operators (>, ==, &, |) to create boolean masks from numeric arrays
  • Avoid Python's built-in sum() on NumPy arrays — it is orders of magnitude slower

Course illustration
Course illustration

All Rights Reserved.