NumPy: Operações Elemento a Elemento
Última atualização: 2026-08-26
1. O que Você Aprenderá
- ❶ Aritmética —
+ - * / // % **e suas funções correspondentes - ❷ Comparação —
> < >= <= == !=gerando máscaras booleanas - ❸ Operações lógicas —
& | ^ ~enp.logical_andetc. - ❹ Vetorização vs loops — comparação de desempenho e princípios
- ❺ Introdução a ufunc — o conceito e propriedades de funções universais
2. História
Bob usa um loop for para elevar ao quadrado 1 milhão de números — leva 0,3 segundos. Alice escreve uma linha a ** 2 — 3 milissegundos.
"A aritmética do NumPy não é um loop Python. É uma operação em lote de ufunc em nível C, 100x mais rápida."
Bob pergunta: "O que é uma ufunc?" Alice abre seu terminal e digita np.add — tudo começa com operações elemento a elemento.
3. Conceitos-Chave
(1) Operadores e Funções Aritméticas
A aritmética do NumPy opera em cada elemento do array, fazendo broadcast automaticamente dos shapes:
import numpy as np
a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])
print(a + b) # [11 22 33 44]
print(a * b) # [10 40 90 160]
print(a ** 2) # [ 1 4 9 16]
print(b // a) # [10 10 10 10]
print(b % a) # [0 0 0 0]
> **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.
Cada operador corresponde a uma função NumPy:
| Operador | Função | Descrição |
|---|---|---|
+ |
np.add |
Adição |
- |
np.subtract |
Subtração |
* |
np.multiply |
Multiplicação |
/ |
np.true_divide |
Divisão real |
// |
np.floor_divide |
Divisão inteira |
% |
np.mod |
Módulo |
** |
np.power |
Potência |
(2) Operações de Comparação
As comparações são elemento a elemento, retornando arrays booleanos (máscaras):
a = np.array([3, 7, 1, 9, 5])
print(a > 4) # [False True False True True]
print(a == 7) # [False True False False False]
print((a >= 3) & (a <= 7)) # [ True True False False True]
> **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.
(3) Operações Lógicas
Use operadores bit a bit & | ^ ~ (não and or not) para combinações lógicas elemento a elemento:
a = np.array([True, True, False, False])
b = np.array([True, False, True, False])
print(a & b) # [ True False False False]
print(a | b) # [ True True True False]
print(~a) # [False False True True]
print(np.logical_and(a, b)) # [ True False False False]
> **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.
(4) Conceito de ufunc
ufunc (função universal) é a abstração de baixo nível do NumPy para operações elemento a elemento:
- Cada ufunc é um loop em nível C que aplica a mesma operação a cada elemento
- Suporta broadcasting, promoção de tipos e buffering de saída
- Possui propriedades
.types,.nin,.nout
print(np.add.nin) # 2 (número de entradas)
print(np.add.nout) # 1 (número de saídas)
print(np.add.types) # lista de assinaturas de tipo suportadas
> **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.
: Operações aritméticas (Dificuldade ⭐)
import numpy as np
a = np.array([2, 4, 6, 8])
b = np.array([1, 3, 5, 7])
print("a + b =", a + b) # [ 3 7 11 15]
print("a - b =", a - b) # [1 1 1 1]
print("a * b =", a * b) # [ 2 12 30 56]
print("a / b =", a / b) # [2. 1.33 1.2 1.14]
print("a // b =", a // b) # [2 1 1 1]
print("a % b =", a % b) # [0 1 1 1]
print("a ** 3 =", a ** 3) # [ 8 64 216 512]
> **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.
: Máscaras de comparação (Dificuldade ⭐)
import numpy as np
scores = np.array([55, 82, 91, 47, 73, 100])
pass_mask = scores >= 60
print("Pass mask:", pass_mask)
print("Pass scores:", scores[pass_mask])
excellent = scores >= 90
print("Excellent:", scores[excellent])
mid_range = (scores >= 60) & (scores < 90)
print("Mid-range:", scores[mid_range])
> **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: Usando o parâmetro out de ufunc (Dificuldade ⭐⭐)
import numpy as np
a = np.array([10, 20, 30, 40])
b = np.array([3, 4, 5, 6])
# Adição in-place usando parâmetro out
result = np.empty(4)
np.add(a, b, out=result)
print("Result:", result)
# Encadear operações com out
np.multiply(result, 2, out=result)
print("Doubled:", result)
# ufunc de comparação
print("a > 15:", np.greater(a, 15))
Output:
TEXT 📖 Somente leituraResult: [13 24 35 46] Doubled: [26 48 70 92] a > 15: [False True True True]
❓ Perguntas Frequentes
P: Por que usar
np.addem vez de+? R: São idênticos —+chamanp.addpor baixo dos panos. Use a forma de função quando precisa de parâmetros extras comodtype,outouwhere, ou quando passa uma ufunc como callback.
P: Divisão por zero gera erro? R: Sem exceção para floats — produz
infou-inf, e0/0produznan, com um aviso opcional baseado emnp.seterr. Divisão inteira por zero geraZeroDivisionError.
P: Vetorização é sempre mais rápida que loops? R: Para arrays grandes com operações simples, vetorização é tipicamente 50-200x mais rápida. Mas para arrays muito pequenos (<100 elementos), a sobrecarga de chamada da ufunc pode torná-la mais lenta que um loop.
P: O que é uma ufunc? R: Uma função universal — um wrapper em nível C para operações elemento a elemento. Cada ufunc lida com broadcasting, promoção de tipos e buffering de saída automaticamente. É o motor por trás da vetorização do NumPy.
📖 Resumo
- Operadores aritméticos
+ - * / // % **são elemento a elemento, cada um com uma funçãonp.xxxcorrespondente - Operadores de comparação geram máscaras booleanas para filtragem condicional
- Operações lógicas usam
& | ^ ~, nãoand or not; funçõesnp.logical_*também funcionam - Vetorização é 50-200x mais rápida que loops Python, impulsionada por ufuncs em nível C
- ufuncs são o motor elemento a elemento do NumPy, suportando broadcasting e promoção de tipos
📝 Exercícios
-
Básico (Dificuldade ⭐): Crie
x = np.linspace(-5, 5, 100). Compute a função sigmoid1 / (1 + np.exp(-x))usando vetorização. Conte quantos resultados são > 0,5. -
Intermediário (Dificuldade ⭐⭐): Compute
np.sin(x)para 1 milhão de números aleatórios usando tanto um loop for quanto vetorização. Compare o tempo e calcule o fator de aceleração. -
Desafio (Dificuldade ⭐⭐⭐): Implemente uma função ReLU vetorizada
max(0, x)parax = np.linspace(-3, 3, 20). Implemente usando tanto uma máscara booleanax * (x > 0)quantonp.maximum(0, x).