Fundamentos do Machine Learning com Python
Exercícios Práticos com Python e NumPy
Aprenda sobre exercícios práticos com python e numpy
🚀 Exercícios Práticos com Python e NumPy
Olá! 👋 Bem-vindo(a) à nossa aula prática do módulo "Introdução ao Python e Ferramentas Essenciais". Nesta sessão, vamos colocar a mão na massa e solidificar seu conhecimento em Python e, especialmente, na biblioteca NumPy, que é a espinha dorsal da computação numérica em Machine Learning.
O objetivo aqui é aprender fazendo. Através de exemplos práticos e desafios, você vai se familiarizar com a criação, manipulação e operações com arrays NumPy, habilidades cruciais para qualquer cientista de dados ou engenheiro de Machine Learning.
Vamos nessa? 🐍✨
🎯 1. Introdução ao NumPy: O Poder dos Arrays
NumPy (Numerical Python) é a biblioteca fundamental para computação científica em Python. Ela fornece um objeto de array multidimensional de alto desempenho, além de ferramentas para trabalhar com esses arrays. Pense nos arrays NumPy como listas Python superpoderosas, otimizadas para operações numéricas.
Por que NumPy? 🤔
- Velocidade: Operações em arrays NumPy são implementadas em C, tornando-as muito mais rápidas do que loops Python puros.
- Memória: Arrays NumPy são mais eficientes em termos de memória do que listas Python para armazenar grandes conjuntos de números.
- Funcionalidade: Oferece uma vasta gama de funções para álgebra linear, transformadas de Fourier e números aleatórios.
Vamos começar criando alguns arrays!
🛠️ 2. Criando Arrays NumPy
A maneira mais comum de criar um array NumPy é a partir de uma lista ou tupla Python.
Exemplo 1: Criando um array a partir de uma lista
import numpy as np
# Criando um array 1D (vetor)
lista_simples = [1, 2, 3, 4, 5]
meu_array_1d = np.array(lista_simples)
print("Array 1D:", meu_array_1d)
print("Tipo do array 1D:", type(meu_array_1d))
print("Dimensões do array 1D:", meu_array_1d.ndim) # Número de dimensões
print("Formato do array 1D:", meu_array_1d.shape) # Tamanho de cada dimensão
print("Tipo de dado dos elementos:", meu_array_1d.dtype)
print("\n" + "="*30 + "\n")
# Criando um array 2D (matriz) a partir de uma lista de listas
lista_de_listas = [[1, 2, 3], [4, 5, 6]]
meu_array_2d = np.array(lista_de_listas)
print("Array 2D:\n", meu_array_2d)
print("Dimensões do array 2D:", meu_array_2d.ndim)
print("Formato do array 2D:", meu_array_2d.shape)Explicação:
np.array()é a função principal para criar arrays.ndimretorna o número de dimensões (eixos) do array.shaperetorna uma tupla indicando o tamanho de cada dimensão. Por exemplo,(2, 3)significa 2 linhas e 3 colunas.dtypemostra o tipo de dado dos elementos no array. NumPy tenta inferir o tipo mais adequado.
Exemplo 2: Funções para criação de arrays especiais
NumPy oferece funções convenientes para criar arrays com valores iniciais específicos.
import numpy as np
# Array de zeros
zeros_array = np.zeros((3, 4)) # Matriz 3x4 de zeros
print("Array de Zeros (3x4):\n", zeros_array)
print("\n" + "="*30 + "\n")
# Array de uns
ones_array = np.ones((2, 2)) # Matriz 2x2 de uns
print("Array de Uns (2x2):\n", ones_array)
print("\n" + "="*30 + "\n")
# Array com valores em um intervalo (semelhante ao range() do Python)
# np.arange(início, fim_exclusivo, passo)
range_array = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
print("Array com arange(0, 10, 2):", range_array)
print("\n" + "="*30 + "\n")
# Array com valores linearmente espaçados
# np.linspace(início, fim_inclusivo, número_de_elementos)
linspace_array = np.linspace(0, 1, 5) # 5 elementos entre 0 e 1 (inclusive)
print("Array com linspace(0, 1, 5):", linspace_array)
print("\n" + "="*30 + "\n")
# Array com números aleatórios
# np.random.rand(dim1, dim2, ...) para números entre 0 e 1
random_array = np.random.rand(2, 3) # Matriz 2x3 de números aleatórios (uniforme)
print("Array Aleatório (rand):\n", random_array)
print("\n" + "="*30 + "\n")
# np.random.randint(low, high_exclusivo, size=(dim1, dim2, ...)) para inteiros
random_int_array = np.random.randint(0, 10, size=(2, 2)) # Matriz 2x2 de inteiros entre 0 e 9
print("Array Aleatório de Inteiros (randint):\n", random_int_array)Explicação:
np.zeros()enp.ones()são úteis para inicializar arrays.np.arange()é excelente para criar sequências numéricas.np.linspace()é ideal quando você precisa de um número específico de pontos igualmente espaçados em um intervalo.np.randomoferece várias funções para gerar números aleatórios, essenciais para simulações e inicialização de modelos.
✂️ 3. Indexação e Fatiamento (Slicing)
Assim como as listas Python, os arrays NumPy podem ser acessados e fatiados.
Exemplo 3: Acessando elementos e fatiando arrays
import numpy as np
arr = np.array([10, 20, 30, 40, 50, 60])
# Acessando um elemento (indexação baseada em zero)
print("Primeiro elemento:", arr[0])
print("Terceiro elemento:", arr[2])
print("Último elemento:", arr[-1])
print("\n" + "="*30 + "\n")
# Fatiamento (slicing)
# arr[início:fim_exclusivo:passo]
print("Elementos do índice 1 ao 3 (exclusivo):", arr[1:4]) # [20, 30, 40]
print("Elementos do início até o índice 2 (exclusivo):", arr[:3]) # [10, 20, 30]
print("Elementos do índice 3 até o final:", arr[3:]) # [40, 50, 60]
print("Todos os elementos com passo de 2:", arr[::2]) # [10, 30, 50]
print("Array invertido:", arr[::-1]) # [60, 50, 40, 30, 20, 10]
print("\n" + "="*30 + "\n")
# Indexação em arrays 2D
matriz = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print("Matriz original:\n", matriz)
print("Elemento na linha 0, coluna 1:", matriz[0, 1]) # Saída: 2
print("Elemento na linha 2, coluna 2:", matriz[2, 2]) # Saída: 9
print("\n" + "="*30 + "\n")
# Fatiamento em arrays 2D
print("Primeira linha:\n", matriz[0, :]) # Ou simplesmente matriz[0]
print("Segunda coluna:\n", matriz[:, 1])
print("Sub-matriz (linhas 0-1, colunas 0-1):\n", matriz[0:2, 0:2])Explicação:
- A indexação funciona de forma similar às listas, mas para arrays multidimensionais, você usa vírgulas para separar os índices de cada dimensão (e.g.,
matriz[linha, coluna]). - O fatiamento também segue a lógica
[início:fim_exclusivo:passo]. - Você pode combinar indexação e fatiamento para extrair sub-arrays complexos.
➕ 4. Operações com Arrays NumPy
A verdadeira força do NumPy reside em suas operações vetorizadas, que são aplicadas elemento a elemento de forma muito eficiente.
Exemplo 4: Operações aritméticas e funções universais (ufuncs)
import numpy as np
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# Adição elemento a elemento
print("arr1 + arr2:", arr1 + arr2)
# Subtração elemento a elemento
print("arr1 - arr2:", arr1 - arr2)
# Multiplicação elemento a elemento
print("arr1 * arr2:", arr1 * arr2)
# Divisão elemento a elemento
print("arr1 / arr2:", arr1 / arr2)
# Potência elemento a elemento
print("arr1 ** 2:", arr1 ** 2)
print("\n" + "="*30 + "\n")
# Operações com um escalar
print("arr1 + 10:", arr1 + 10)
print("arr1 * 3:", arr1 * 3)
print("\n" + "="*30 + "\n")
# Funções universais (ufuncs)
# Funções matemáticas que operam elemento a elemento
print("np.sqrt(arr2):", np.sqrt(arr2)) # Raiz quadrada
print("np.sin(arr1):", np.sin(arr1)) # Seno
print("np.log(arr2):", np.log(arr2)) # Logaritmo natural
print("\n" + "="*30 + "\n")
# Funções de agregação
matriz = np.array([[1, 2, 3],
[4, 5, 6]])
print("Matriz original:\n", matriz)
print("Soma de todos os elementos:", matriz.sum())
print("Valor máximo:", matriz.max())
print("Valor mínimo:", matriz.min())
print("Média:", matriz.mean())
# Agregação por eixo (axis)
# axis=0 -> opera ao longo das colunas (resultado por linha)
# axis=1 -> opera ao longo das linhas (resultado por coluna)
print("Soma por coluna (axis=0):", matriz.sum(axis=0)) # [1+4, 2+5, 3+6] -> [5, 7, 9]
print("Soma por linha (axis=1):", matriz.sum(axis=1)) # [1+2+3, 4+5+6] -> [6, 15]Explicação:
- Operações aritméticas são aplicadas elemento a elemento por padrão.
- Funções universais (ufuncs) como
np.sqrt(),np.sin(), etc., também operam elemento a elemento. - Funções de agregação como
sum(),max(),min(),mean()podem ser aplicadas ao array inteiro ou ao longo de um eixo específico (axis).
🔄 5. Remodelando Arrays (Reshaping)
Muitas vezes, você precisará mudar a forma (formato) de um array sem alterar seus dados. reshape() é a função para isso.
Exemplo 5: Remodelando um array
import numpy as np
arr = np.arange(1, 10) # Array de 1 a 9
print("Array original:", arr)
print("Formato original:", arr.shape)
print("\n" + "="*30 + "\n")
# Remodelando para uma matriz 3x3
matriz_3x3 = arr.reshape((3, 3))
print("Matriz 3x3:\n", matriz_3x3)
print("Formato da matriz:", matriz_3x3.shape)
print("\n" + "="*30 + "\n")
# O argumento -1 pode ser usado para que o NumPy calcule a dimensão
# Ex: reshape((3, -1)) significa 3 linhas e NumPy calcula o número de colunas
matriz_3xN = arr.reshape((3, -1))
print("Matriz 3xN:\n", matriz_3xN)
print("Formato da matriz 3xN:", matriz_3xN.shape)
print("\n" + "="*30 + "\n")
# Remodelando um array 2D para 1D (achatando)
matriz_2d = np.array([[1, 2, 3], [4, 5, 6]])
arr_flat = matriz_2d.flatten() # Cria uma cópia achatada
arr_ravel = matriz_2d.ravel() # Cria uma view achatada (mais eficiente para grandes arrays)
print("Matriz 2D original:\n", matriz_2d)
print("Array achatado (flatten):", arr_flat)
print("Array achatado (ravel):", arr_ravel)Explicação:
reshape()permite alterar o formato de um array, desde que o número total de elementos permaneça o mesmo.- Usar
-1em uma das dimensões permite que o NumPy calcule automaticamente o tamanho dessa dimensão. flatten()eravel()são usados para "achatar" um array multidimensional em um array 1D.flatten()retorna uma cópia, enquantoravel()retorna uma view (se possível), o que pode ser mais eficiente em termos de memória.
🏋️♀️ 6. Exercícios Práticos
Agora é a sua vez! Use o que você aprendeu para resolver os desafios abaixo. Não se preocupe em errar, o importante é praticar!
Desafio 1: Criando e Inspecionando Arrays 📊
Crie um array NumPy e inspecione suas propriedades.
- Crie um array 1D chamado
vetor_idadescom as idades[22, 25, 30, 19, 45]. - Crie um array 2D chamado
matriz_dadoscom 3 linhas e 4 colunas, contendo números inteiros aleatórios entre 10 e 50. - Imprima o
shape,ndimedtypede ambos os arrays.
💡 Dica
Use np.array() para o vetor e np.random.randint() para a matriz. Lembre-se dos atributos .shape, .ndim e .dtype.
# Escreva seu código aqui para o Desafio 1
import numpy as np
# Crie vetor_idades
vetor_idades = np.array([22, 25, 30, 19, 45])
# Crie matriz_dados
matriz_dados = np.random.randint(10, 51, size=(3, 4)) # 51 porque o high é exclusivo
# Imprima as propriedades
print("Vetor de Idades:")
print(" Array:", vetor_idades)
print(" Shape:", vetor_idades.shape)
print(" Ndim:", vetor_idades.ndim)
print(" Dtype:", vetor_idades.dtype)
print("\nMatriz de Dados:")
print(" Array:\n", matriz_dados)
print(" Shape:", matriz_dados.shape)
print(" Ndim:", matriz_dados.ndim)
print(" Dtype:", matriz_dados.dtype)Desafio 2: Manipulação e Fatiamento 🔪
Trabalhe com um array 2D para extrair e modificar elementos.
- Crie uma matriz 4x4 chamada
matriz_basecom números de 1 a 16. - Extraia a segunda linha da
matriz_base. - Extraia a terceira coluna da
matriz_base. - Extraia a sub-matriz formada pelas duas últimas linhas e as duas primeiras colunas.
- Altere todos os elementos da primeira linha da
matriz_basepara 0. Imprima a matriz modificada.
💡 Dica
Use np.arange() e reshape() para criar a matriz. Lembre-se da sintaxe matriz[linha, coluna] para indexação e fatiamento. Para modificar, atribua novos valores diretamente.
# Escreva seu código aqui para o Desafio 2
import numpy as np
# Crie matriz_base
matriz_base = np.arange(1, 17).reshape((4, 4))
print("Matriz Base Original:\n", matriz_base)
# Extraia a segunda linha
segunda_linha = matriz_base[1, :]
print("\nSegunda linha:", segunda_linha)
# Extraia a terceira coluna
terceira_coluna = matriz_base[:, 2]
print("Terceira coluna:", terceira_coluna)
# Extraia a sub-matriz
sub_matriz = matriz_base[2:, :2]
print("Sub-matriz (últimas 2 linhas, primeiras 2 colunas):\n", sub_matriz)
# Altere a primeira linha para 0
matriz_base[0, :] = 0
print("\nMatriz Base com primeira linha zerada:\n", matriz_base)Desafio 3: Operações e Agregações ➕➖
Realize operações matemáticas e agregações em arrays.
- Crie dois arrays 1D,
a = np.array([10, 20, 30])eb = np.array([3, 4, 5]). - Calcule
aelevado à potência deb(elemento a elemento). - Calcule a raiz quadrada de cada elemento de
a. - Crie uma matriz 3x3 com números inteiros aleatórios entre 1 e 10.
- Calcule a soma de todos os elementos da matriz.
- Calcule a média de cada coluna da matriz.
💡 Dica
Use ** para potência, np.sqrt() para raiz quadrada. Para a soma e média, use os métodos .sum() e .mean() e explore o parâmetro axis.
# Escreva seu código aqui para o Desafio 3
import numpy as np
# Crie arrays a e b
a = np.array([10, 20, 30])
b = np.array([3, 4, 5])
# Calcule a elevado a b
potencia_ab = a ** b
print("a elevado a b:", potencia_ab)
# Calcule a raiz quadrada de a
raiz_a = np.sqrt(a)
print("Raiz quadrada de a:", raiz_a)
# Crie uma matriz 3x3 aleatória
matriz_aleatoria = np.random.randint(1, 11, size=(3, 3))
print("\nMatriz Aleatória:\n", matriz_aleatoria)
# Soma de todos os elementos
soma_total = matriz_aleatoria.sum()
print("Soma total dos elementos:", soma_total)
# Média de cada coluna
media_colunas = matriz_aleatoria.mean(axis=0)
print("Média de cada coluna:", media_colunas)📝 7. Resumo e Próximos Passos
Parabéns por completar esta aula prática! 🎉 Você deu passos importantes para dominar o NumPy.
Nesta aula, você aprendeu a:
- Criar arrays NumPy de diversas formas (
np.array,np.zeros,np.ones,np.arange,np.linspace,np.random). - Inspecionar as propriedades de um array (
.shape,.ndim,.dtype). - Acessar e fatiar elementos em arrays 1D e 2D.
- Realizar operações aritméticas e usar funções universais (ufuncs) em arrays.
- Aplicar funções de agregação (
.sum(),.mean(),.max(),.min()) em arrays e ao longo de eixos específicos. - Remodelar arrays usando
reshape(),flatten()eravel().
Essas são as bases para qualquer trabalho com dados e Machine Learning em Python. O NumPy é uma ferramenta incrivelmente poderosa e eficiente, e sua proficiência nela será um diferencial.
Próximos Passos:
- Continue praticando: A melhor forma de aprender é fazendo. Tente criar seus próprios arrays e realizar diferentes operações.
- Explore a documentação oficial do NumPy: NumPy Documentation é uma excelente fonte para aprofundar seus conhecimentos e descobrir mais funcionalidades.
- Prepare-se para a próxima aula: No próximo módulo, exploraremos a biblioteca Pandas, que se baseia no NumPy para manipulação e análise de dados tabulares.
Até a próxima! Feliz codificação! 🚀💻