numpy.where() selects values from two array-like inputs based on a Boolean condition. It can also return the indices where a condition is true when only the condition is supplied.

The syntax of numpy.where() is:

</>
Copy
 numpy.where(condition[, x, y])

If an element of condition is true, the corresponding element from x is selected. If it is false, the corresponding element from y is selected. The condition, x, and y are broadcast together when their shapes are compatible.

When only condition is given, numpy.where(condition) returns a tuple of index arrays, equivalent to calling condition.nonzero(). For subclasses of ndarray, NumPy recommends using nonzero() directly when only indices are required.

NumPy where() syntax and parameters

  • condition: A Boolean array or an expression that produces Boolean values.
  • x: Values selected where the condition is true.
  • y: Values selected where the condition is false.

If either x or y is provided, both must be provided. The result has the broadcast shape of condition, x, and y.

Example 1 – NumPy where() selecting values from two arrays

This example demonstrates the two selection branches: when the condition is true, values come from a+2; when it is false, values come from b+2.

>>> a = np.random.randint(1,10,8).reshape(2,4)
>>> b = np.random.randint(1,10,8).reshape(2,4)
>>> a
array([[6, 8, 8, 8],
       [1, 3, 9, 2]])
>>> b
array([[9, 7, 6, 8],
       [7, 8, 2, 7]])
>>> np.where(4<5, a+2, b+2)
array([[ 8, 10, 10, 10],
       [ 3,  5, 11,  4]])
>>> np.where(4>5, a+2, b+2)
array([[11,  9,  8, 10],
       [ 9, 10,  4,  9]])
>>>

In np.where(4<5, a+2, b+2), the scalar condition is true, so every output value is taken from a+2.

In np.where(4>5, a+2, b+2), the scalar condition is false, so every output value is taken from b+2.

Example 2 – NumPy where() indices in a two-dimensional array

When only a condition is supplied, numpy.where() returns one index array for each dimension. The following example finds the positions of even values in a two-dimensional array.

>>> a = np.random.randint(1,10,8).reshape(2,4)
>>> a
array([[9, 8, 1, 4],
       [9, 1, 5, 4]])
>>> w = np.where(a%2==0)
>>> w
(array([0, 0, 1], dtype=int32), array([1, 3, 3], dtype=int32))
>>>

The first returned array contains row indices, and the second contains column indices. Pairing values at the same positions gives the coordinates (0, 1), (0, 3), and (1, 3).

Those coordinates refer to the even elements 8, 4, and 4. You can retrieve them directly with a[w].

</>
Copy
even_values = a[w]
print(even_values)
[8 4 4]

Example 3 – NumPy where() with multiple conditions

The following existing example passes a list containing two Boolean arrays. NumPy converts that list into a stacked three-dimensional Boolean array, so the returned tuple contains indices for three dimensions. This is different from combining two conditions with logical AND or logical OR.

>>> a = np.random.randint(1,10,8).reshape(2,4)
>>> b = np.random.randint(1,10,8).reshape(2,4)
>>> a
array([[6, 8, 8, 8],
       [1, 3, 9, 2]])
>>> b
array([[9, 7, 6, 8],
       [7, 8, 2, 7]])
>>> np.where([a>10,b<8])
(array([1, 1, 1, 1, 1], dtype=int32), array([0, 0, 1, 1, 1], dtype=int32), array([1, 2, 0, 2, 3], dtype=int32))

In this result, the first index array identifies which stacked condition matched, while the second and third arrays contain the row and column indices. Because a>10 has no true values, all matches come from the second condition, b<8.

To find positions where two conditions are both true, combine the Boolean expressions with & and place each comparison in parentheses.

</>
Copy
indices = np.where((a > 5) & (b < 8))
print(indices)
(array([0, 0], dtype=int32), array([1, 2], dtype=int32))

For logical OR, use | instead of &. Do not use Python’s and or or with NumPy arrays because those operators expect one Boolean value rather than an element-wise Boolean array.

Example 4 – NumPy where() indices in a one-dimensional array

>>> import numpy as np
>>> a = np.random.randint(1,10,8)
>>> a
array([6, 2, 9, 1, 8, 4, 6, 4])
>>> w = np.where(a>5)
>>> w
(array([0, 2, 4, 6], dtype=int32),)
>>>

The condition is a>5. It is true at indices 0, 2, 4, and 6, so the function returns those positions.

The result is a one-item tuple because the input array has one dimension. Use w[0] to obtain the index array itself, or use a[w] to retrieve the matching values.

You can store this result in a variable and access individual indices.

>>> w[0][3]
6
>>> w[0][1]
2

Replacing array values with NumPy where()

A common use of numpy.where() is to replace values without modifying the original array. This example keeps non-negative values and replaces negative values with zero.

</>
Copy
import numpy as np

values = np.array([-4, 2, -1, 7, 0])
result = np.where(values >= 0, values, 0)

print(result)
[0 2 0 7 0]

The result is a new array. The original values array is unchanged.

Using scalar values and broadcasting in NumPy where()

The x and y arguments do not have to be arrays of exactly the same shape as the condition. NumPy can broadcast compatible scalars and arrays.

</>
Copy
scores = np.array([42, 75, 61, 89])
labels = np.where(scores >= 60, "pass", "fail")

print(labels)
['fail' 'pass' 'pass' 'pass']

Here, the string scalars "pass" and "fail" are broadcast to the shape of scores.

NumPy where(), argwhere(), nonzero(), and select()

  • Use numpy.where(condition, x, y) when you need element-wise selection between two choices.
  • Use numpy.nonzero(condition) when you need one index array per dimension.
  • Use numpy.argwhere(condition) when you want matching coordinates grouped by row, such as [[0, 1], [0, 3], [1, 3]].
  • Use numpy.select() when you have several conditions and several corresponding choices.

For two-dimensional and higher-dimensional data, argwhere() is often easier to read when you want a list of coordinates. The tuple returned by where() or nonzero() is more convenient for indexing an array directly.

Common NumPy where() mistakes

  • Using and or or instead of element-wise & or |.
  • Forgetting parentheses around comparisons in combined conditions.
  • Expecting np.where(condition) to return matching values instead of index arrays.
  • Assuming a one-dimensional result is an array rather than a one-item tuple.
  • Passing only one of x or y; both are required for value selection.
  • Using arrays with shapes that cannot be broadcast together.

NumPy where() FAQs

How do I use NumPy where() with two conditions?

Combine conditions element by element. Use np.where((a > 5) & (b < 8)) for AND, or np.where((a > 5) | (b < 8)) for OR. Parentheses around each comparison are required.

How do I get values instead of indices from NumPy where()?

Store the returned tuple and use it to index the array: indices = np.where(condition), followed by values = array[indices]. Alternatively, use the three-argument form to select values from x and y.

What does NumPy where() return for a two-dimensional array?

With only a condition, it returns a tuple containing two arrays: one for row indices and one for column indices. With x and y, it returns an array of selected values.

What is the difference between NumPy where() and argwhere()?

where(condition) returns separate index arrays for each dimension. argwhere(condition) groups each matching coordinate into a row. Use where() for direct advanced indexing and argwhere() when grouped coordinates are easier to work with.

Does NumPy where() change the original array?

No. The three-argument form returns a new array containing the selected values. Assign the result back to a variable if you want to replace the original reference.

Editorial QA checklist for this NumPy where() tutorial

  • Confirm that examples distinguish value selection from index lookup.
  • Check that combined conditions use & or | with parentheses.
  • Verify that two-dimensional index tuples are explained as row and column arrays.
  • Ensure output shown for each deterministic example matches the code.
  • Confirm that comparisons with argwhere(), nonzero(), and select() match their intended use.