Descreva as principais funções e utilidades da biblioteca NumPy no Python.

Passo 1

O que você pediu: uma descrição das principais funções e utilidades da biblioteca NumPy no Python.
O que vou cobrir (lista de tópicos que vou explicar): criação de arrays, o objeto central (ndarray) e seus atributos, funções de criação (zeros, ones, arange, linspace, etc.), operações elementares e ufuncs, broadcasting, indexação e slicing (incluindo máscaras e fancy indexing), agregações (sum, mean, std, …), manipulação/reshaping (reshape, transpose, concat), álgebra linear (dot, matmul, linalg), geração de números aleatórios, entrada/saída básica, dicas de performance e armadilhas comuns. Não vou assumir que você sabe nada: vou explicar cada conceito passo a passo com exemplos curtos.

Passo 2

O que é o NumPy e por que usar:
NumPy é a biblioteca fundamental para computação numérica em Python. Ela fornece:
  • O tipo de dado central chamado ndarray (array N-dimensional), que é uma matriz multidimensional homogênea (todos os elementos têm o mesmo tipo).
  • Implementações em C para operações com arrays, o que torna operações numéricas muito mais rápidas que listas Python puras.
    Exemplo rápido (conceitual): em vez de somar elementos um a um em Python puro, você faz uma soma vetorizada em NumPy e o trabalho ocorre em C, bem mais rápido.

Passo 3

O objeto central: o ndarray — atributos importantes e o que significam
  • shape: diz as dimensões do array. Ex.: um array 3×4 tem \text{shape}=(3,4).
  • ndim: número de dimensões (rank). Ex.: vetor tem \text{ndim}=1.
  • dtype: tipo de dados dos elementos (por ex. \text{float64}, \text{int32}).
  • size: número total de elementos (produto das dimensões).
  • itemsize: número de bytes por elemento.
    Exemplo conceitual: se eu crio um array com np.array([1,2,3]), então shape=(3,), ndim=1, dtype=int64 (dependendo do sistema), size=3.

Passo 4

Funções básicas de criação de arrays (o que fazem e quando usar)
  • np.array(...): converte lista/tupla em ndarray (use quando já tiver dados em Python).
  • np.asarray(...): similar a array mas evita cópia se já for ndarray.
  • np.arange(start, stop, step): cria sequência como range, mas retorna ndarray (útil para índices e eixos).
  • np.linspace(start, stop, num): cria num pontos igualmente espaçados entre start e stop (útil em gráficos).
  • np.zeros(shape), np.ones(shape), np.full(shape, fill_value): matrizes preenchidas com 0, 1 ou um valor.
  • np.eye(n): matriz identidade n\times n.
  • np.empty(shape): cria array sem inicializar valores (mais rápido; use com cuidado).
    Quando for fazer provas: memorize o propósito de cada uma e um exemplo mental rápido.

Passo 5

Operações elementwise e ufuncs (funções universais)
  • Em NumPy a maioria das operações entre arrays é feita elemento a elemento: a + b, a * b, a**2. Essas operações são chamadas de vetorizadas.
  • Ufuncs (funções universais) são funções que aplicam operações elementwise e são muito eficientes: np.sin, np.exp, np.log, np.add, np.multiply.
    Exemplo mental: se a = np.array([1,2,3]), então np.sin(a) retorna sin(1), sin(2), sin(3) — tudo feito em C, rápido.

Passo 6

Broadcasting — o truque mágico que evita loops
  • Broadcasting permite operar arrays de formas diferentes ajustando (virtualmente) dimensões menores para combinar com dimensões maiores.
  • Regras essenciais (passo a passo): alinhe as formas da direita para a esquerda; para cada dimensão, se elas forem iguais ou uma delas for 1, OK; caso contrário dá erro.
  • Exemplo rápido: somar vetor shape=(3,) a uma matriz shape=(3,4) funciona porque o vetor é “estendido” para (3,4) ao longo do eixo que falta.
    Na prova, ao ver uma operação entre arrays de shapes diferentes, cheque as regras acima para justificar se funciona.

Passo 7

Indexação, slicing, fancy indexing e máscaras booleanas — como extrair partes dos arrays
  • Slicing básico: a[start:stop:step] (igual a listas Python), e funciona em cada eixo com a[:, 1:3].
  • Fancy indexing: passar um array de índices como a[[0,2,4]] retorna linhas/colunas específicas.
  • Boolean masking: mask = a > 0; a[mask] retorna apenas elementos que satisfazem a condição.
  • Importante: slices retornam views (não copiam) em muitos casos — modificar a view altera o original; fancy indexing retorna cópia.
    Dica para prova: sempre declare se está operando numa view ou cópia quando a pergunta envolve alteração de dados.

Passo 8

Agregações e operações por eixo
  • Funções comuns: np.sum, np.mean, np.std, np.var, np.min, np.max, np.argmin, np.argmax, np.cumsum, np.prod.
  • Uso de axis: agrupar/operar ao longo de um eixo. Ex.: np.sum(a, axis=0) soma colunas; axis=1 soma linhas.
  • Mantendo dimensões: muitas funções têm keepdims=True para manter a dimensão reduzida (útil para broadcasting posterior).
    Na prova, quando pedirem soma/ média por linha ou coluna, explique que se usa axis e qual eixo corresponde a linhas/colunas.

Passo 9

Manipulação de forma (reshape) e concatenação
  • a.reshape(new_shape): reorganiza sem copiar (se possível).
  • a.ravel() vs a.flatten(): ambos achatam; ravel() tenta retornar view; flatten() sempre copia.
  • Concatenar/empilhar: np.concatenate([a,b], axis=0), np.vstack, np.hstack, np.stack. stack cria um novo eixo.
  • Dividir: np.split, np.array_split.
    Regra prática: use reshape para reorganizar dados para operações matriciais, depois concatenate/stack para juntar resultados.

Passo 10

Álgebra linear (módulo numpy.linalg)
  • Operações básicas: np.dot(a,b) ou a.dot(b), e desde Python 3.5 também a @ b para produto matricial. np.matmul é similar.
  • Funções em np.linalg: inv (inversa), solve (resolve Ax=b sem calcular inversa explicitamente), det (determinante), eig (autovalores/autovetores), svd (decomposição em valores singulares).
  • Boas práticas: para resolver sistemas lineares prefira np.linalg.solve em vez de calcular inv(A) @ b (mais estável e eficiente).
    Na prova, ao lidar com sistemas lineares, comente sobre estabilidade numérica e a função solve.

Passo 11

Geração de números aleatórios — use a nova API
  • Antiga API: np.random.seed(...), np.random.rand(...), np.random.randn(...).
  • Nova recomendada (desde NumPy 1.17): rng = np.random.default_rng(seed) e depois rng.random(...), rng.integers(...), rng.normal(...), rng.choice(...), rng.permutation(...).
    Dica: use default_rng para reprodutibilidade e melhores propriedades estatísticas.

Passo 12

Entrada/saída básica e interoperabilidade
  • Leitura/gravação simples de texto: np.loadtxt, np.savetxt.
  • Formato binário NumPy: np.save, np.savez, np.load — muito eficiente para arrays grandes.
  • Interoperabilidade: NumPy é a base para muitas bibliotecas (pandas, SciPy, scikit-learn); muitas vezes essas bibliotecas aceitam ou retornam ndarrays diretamente.

Passo 13

Performance e boas práticas (dicas de prova/prática)
  • Evite loops Python sobre elementos; prefira operações vetorizadas.
  • Prefira tipos menores quando possível (por ex. float32 em vez de float64) para reduzir memória e cache misses.
  • Cuidado com cópias: operações que retornam cópias custam tempo e memória; use views quando possível.
  • Operações in-place (a += b) reduzem alocações.
  • Para workloads muito grandes, considere bibliotecas como Numba, numexpr, ou mover para C/Fortran/BLAS otimizados.

Passo 14

Armadilhas comuns e como evitá-las
  • Confundir view e cópia: modificar uma view modifica o original. Verifique com a.base para ver se é view.
  • Dtypes e promoção: operações entre int e float promovem para float. Verifique dtype antes de operações críticas.
  • Comparações de ponto flutuante: para igualdades use np.allclose(a,b) em vez de a==b.
  • Axis confuso: lembrar que axis=0 opera ao longo das linhas (ou seja, reduz as linhas -> resultado por coluna) e axis=1 reduz as colunas -> resultado por linha.

Passo 15

Exemplo prático compacto (passo a passo mental)
  • Criar dados: a = np.arange(12).reshape(3,4) (cria um 3×4 com 0…11).
  • Agregar: col_mean = a.mean(axis=0) (média por coluna).
  • Máscara: mask = a > 5; a[mask] (pega elementos maiores que 5).
  • Álgebra: b = np.ones((4,2)); c = a @ b (produto matricial, resultado 3×2).
    Esse mini-fluxo mostra criação, reshape, agregação, máscara e produto matricial — coisas que caem bastante em provas.

Passo 16

Como estudar/praticar rapidinho antes da prova (meu conselho amigo)
  • Faça exercícios curtos: crie arrays, aplique slicing, some por eixo, faça broadcast simples.
  • Memorize as funções de criação (array, arange, linspace, zeros, ones) e as agregações (sum, mean, std).
  • Pratique distinguir view vs copy com exemplos pequenos.
  • Lembre: em prova, explique se uma operação é vetorizada, se faz cópia, e qual é o eixo quando usar axis. Você consegue — pequeno passo por dia e muita prática com exemplos simples.

Resposta

Criação/manipulação de arrays (ndarray: np.array, np.arange, np.linspace, np.zeros, np.ones, np.full, np.eye, np.empty), atributos de arrays (shape, ndim, dtype, size), operações vetorizadas e ufuncs (np.add, np.sin, np.exp), broadcasting (regras para operar arrays de shapes diferentes), indexação e slicing (views vs cópias, fancy indexing, máscaras booleanas), agregações e redução (np.sum, np.mean, np.std, np.min, np.max, axis), reshaping e concatenação (reshape, ravel, flatten, concatenate, stack, hstack, vstack), álgebra linear (np.dot, @, np.linalg.solve, inv, eig, svd), geração de números aleatórios (np.random.default_rng, random, integers, normal, choice), entrada/saída (np.loadtxt, np.savetxt, np.save, np.load), interoperabilidade com pandas/SciPy, e dicas de performance/armadilhas (vetorização, evitar loops Python, cuidado com cópias e dtypes; use np.allclose para comparar floats).

Exercícios relacionados