NumPy: Indexação Booleana e Fancy
Última atualização: 2026-08-26
1. O que Você Aprenderá
- ❶ Máscaras booleanas — usando expressões condicionais para gerar arrays True/False para filtragem
- ❷
np.where— seleção condicional ternária e substituição de elementos - ❸ Indexação fancy — selecionando elementos em ordem arbitrária com arrays de inteiros
- ❹ Indexação combinada — misturando indexação básica e avançada
- ❺ Indexação avançada retorna cópias — a diferença chave em relação às views
2. História
Alice tem 100.000 leituras de temperatura e precisa encontrar todas acima de 40°C. Ela escreve temps[temps > 40] e obtém o resultado instantaneamente. Bob está impressionado: "Um loop Python com instruções if levaria pelo menos 5 linhas — o NumPy faz em uma linha, quase 100x mais rápido!" Este é o poder da indexação avançada do NumPy — filtragem de dados complexa com expressões concisas.
3. Máscaras Booleanas
(1) O Que É uma Máscara Booleana
Uma máscara booleana é um array True/False com o mesmo shape do original. Os operadores de comparação do NumPy funcionam elemento a elemento e retornam arrays booleanos.
import numpy as np
arr = np.array([3, -1, 4, -2, 5])
mask = arr > 0
print(mask) # [ True False True False True]
print(arr[mask]) # [3 4 5]
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
(2) Operadores de Comparação
| Operador | Significado | Função Equivalente |
|---|---|---|
> |
Maior que | np.greater |
>= |
Maior ou igual | np.greater_equal |
< |
Menor que | np.less |
<= |
Menor ou igual | np.less_equal |
== |
Igual | np.equal |
!= |
Diferente | np.not_equal |
(3) Combinações Lógicas
Combine múltiplas condições com operadores lógicos — use & (and), | (or), ~ (not), não and/or/not do Python. Cada condição deve ser envolvida em parênteses.
arr = np.array([1, 5, 8, 3, 9, 2])
mask = (arr > 3) & (arr < 8) # 3 < arr < 8
print(arr[mask]) # [5]
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
| Operação Lógica | Significado | Função Equivalente |
|---|---|---|
& |
AND lógico | np.logical_and |
| |
OR lógico | np.logical_or |
~ |
NOT lógico | np.logical_not |
4. np.where e Seleção Condicional
(1) Forma com três argumentos: np.where(condition, x, y)
Retorna elementos de x onde a condição é True, de y onde é False.
import numpy as np
arr = np.array([-3, 5, -1, 8, -2, 7])
result = np.where(arr > 0, arr, 0)
print(result) # [0 5 0 8 0 7]
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
(2) Forma com um argumento: np.where(condition)
Retorna os índices onde a condição é True.
indices = np.where(arr > 0)
print(indices) # (array([1, 3, 5]),)
print(arr[indices]) # [5 8 7]
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
5. Indexação Fancy
Indexação fancy usa arrays de inteiros para selecionar elementos em qualquer ordem.
import numpy as np
a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
# Selecionar índices específicos
print(a[[0, 3, 7]]) # [0 3 7]
# Selecionar em qualquer ordem, com repetições
print(a[[5, 5, 1, 9]]) # [5 5 1 9]
# Indexação fancy 2D
b = np.arange(12).reshape(3, 4)
print(b[[0, 2]]) # linhas 0 e 2
print(b[:, [0, 2, 3]]) # colunas 0, 2, 3 para todas as linhas
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
▶ Exemplo
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
: Filtragem com máscara booleana (Dificuldade ⭐)
import numpy as np
scores = np.array([55, 82, 91, 47, 73, 100, 68])
passing = scores[scores >= 60]
print("Passing:", passing) # [82 91 73 100 68]
excellent = scores[scores >= 90]
print("Excellent:", excellent) # [91 100]
# Múltiplas condições
mid = scores[(scores >= 60) & (scores < 90)]
print("Mid-range:", mid) # [82 73 68]
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
▶ Exemplo
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
: np.where para substituição condicional (Dificuldade ⭐⭐)
import numpy as np
# Limitar ao intervalo: substituir valores fora de [0, 100]
data = np.array([-5, 120, 30, -20, 80, 200])
clipped = np.where(data < 0, 0, np.where(data > 100, 100, data))
print("Clipped:", clipped) # [ 0 100 30 0 80 100]
# Categorizar
grades = np.array([45, 72, 88, 55, 91])
letter = np.where(grades >= 85, 'A',
np.where(grades >= 70, 'B',
np.where(grades >= 60, 'C', 'D')))
print("Grades:", letter) # ['D' 'B' 'A' 'D' 'A']
> **Output:** Execute o NumPy 2.x em seu ambiente Python local para ver a saída do ndarray. O servidor Piston não tem o NumPy pré-instalado — instale-o localmente (`pip install numpy`) e compare. Os valores reais podem variar conforme a versão do NumPy e a semente aleatória.
6. Tabelas Comparativas
(1) Métodos de Indexação
| Método | Sintaxe | Retorna | Copia? | Caso de Uso |
|---|---|---|---|---|
| Fatia básica | a[1:3] |
View | Não | Sub-array, intervalo contíguo |
| Índice inteiro | a[2] |
Escalar | N/A | Elemento único |
| Máscara booleana | a[mask] |
Array 1D | Sim | Filtragem condicional |
| Indexação fancy | a[[1,3,5]] |
Array | Sim | Seleção em ordem arbitrária |
| np.where | np.where(cond, x, y) |
Array | Sim | Seleção ternária |
(2) Booleana vs Fancy
| Característica | Máscara Booleana | Indexação Fancy |
|---|---|---|
| Sintaxe | arr[arr > 0] |
arr[[1, 3, 5]] |
| Lógica de seleção | Baseada em condição | Baseada em posição |
| Shape do resultado | 1D (achatado) | Mesmo shape do array de índices |
| Velocidade | Rápida para máscaras grandes | Rápida para seleção esparsa |
▶ Exemplo: Indexação fancy 2D com np.ix_ (Dificuldade ⭐⭐)
import numpy as np
arr = np.arange(20).reshape(4, 5)
print("Original:\n", arr)
# Selecionar linhas e colunas específicas
rows = [0, 2, 3]
cols = [1, 3]
result = arr[np.ix_(rows, cols)]
print("Rows [0,2,3], Cols [1,3]:\n", result)
# Modificar elementos selecionados
arr[np.ix_([0, 1], [0, 4])] = -1
print("After modification:\n", arr)
Output:
TEXT 📖 Somente leituraOriginal: [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]] Rows [0,2,3], Cols [1,3]: [[ 1 3] [11 13] [16 18]] After modification: [[-1 1 2 3 -1] [-1 6 7 8 -1] [10 11 12 13 14] [15 16 17 18 19]]
❓ Perguntas Frequentes
P: Posso usar uma máscara booleana para modificar valores? R: Sim!
arr[arr > 0] = 0define todos os valores positivos como 0. Esta é uma modificação in-place.np.where(arr > 0, 0, arr)retorna um novo array em vez disso.
P: Qual é a diferença entre arr[mask] e np.where(mask)? R:
arr[mask]retorna os valores onde a máscara é True.np.where(mask)retorna os índices onde a máscara é True. Usearr[mask]para os valores,np.where(mask)quando precisa de posições.
P: Posso usar indexação fancy com arrays 2D? R: Sim.
arr[[0,2], [1,3]]seleciona os elementos em (0,1) e (2,3). Para seleção independente de linha/coluna, usearr[np.ix_([0,2], [1,3])].
P: Máscaras booleanas sempre retornam arrays 1D? R: Para arrays 2D+, sim — a máscara achata o resultado para 1D. Use
np.where(mask)para obter os índices no shape original.
📖 Resumo
- Máscaras booleanas:
arr[arr > 0]— filtrar por condição, retorna uma cópia - Combinações lógicas: use
&,|,~com parênteses ao redor de cada condição np.where(cond, x, y): seleção ternária — retorna x onde True, y onde Falsenp.where(cond): retorna índices onde a condição é True- Indexação fancy:
arr[[i1, i2, ...]]— selecionar por índices inteiros arbitrários - Indexação avançada (booleana + fancy) sempre retorna uma cópia, não uma view
📝 Exercícios
-
Básico (Dificuldade ⭐): Crie um array de 20 inteiros aleatórios entre -10 e 10. Use uma máscara booleana para extrair todos os valores positivos. Use
np.wherepara substituir todos os valores negativos por 0. -
Intermediário (Dificuldade ⭐⭐): Crie um array 5x5 de inteiros aleatórios 0-100. Use máscaras booleanas para: (a) contar valores acima de 50, (b) substituir valores abaixo de 20 por 20, (c) extrair os índices de linha e coluna de todos os valores > 80 usando
np.where. -
Desafio (Dificuldade ⭐⭐⭐): Crie um array 10x4 de notas de estudantes (10 estudantes, 4 matérias). Use indexação fancy para: (a) selecionar estudantes nas posições [0,3,7] para todas as matérias, (b) selecionar matérias nas posições [1,3] para todos os estudantes, (c) calcular a média dos 3 melhores estudantes por nota total.