Fundamentos do Machine Learning com Python
Introdução ao Pandas: Series e DataFrames (Documentação Pandas)
Aprenda sobre introdução ao pandas: series e dataframes (documentação pandas)
🐼 Introdução ao Pandas: Series e DataFrames
Olá, futuros cientistas de dados! 👋 Sejam bem-vindos à aula de Introdução ao Pandas, uma das bibliotecas mais poderosas e essenciais para manipulação e análise de dados em Python. Nesta aula, vamos mergulhar nas duas estruturas de dados fundamentais do Pandas: Series e DataFrames.
1. 🚀 Introdução ao Pandas
O que é Pandas?
Pandas é uma biblioteca de código aberto para a linguagem de programação Python que fornece estruturas de dados de alto desempenho e ferramentas de análise de dados fáceis de usar. O nome "Pandas" é derivado de "Panel Data", um termo econométrico para dados multidimensionais.
Por que usar Pandas?
Se você trabalha com dados tabulares (como planilhas Excel, bancos de dados SQL ou arquivos CSV), o Pandas é sua ferramenta ideal. Ele oferece:
- Estruturas de Dados Robustas:
Series(1D) eDataFrame(2D) são otimizadas para manipulação de dados. - Leitura e Escrita Fácil: Suporte para diversos formatos de arquivo (CSV, Excel, SQL, JSON, HDF5, etc.).
- Manipulação de Dados Flexível: Indexação, seleção, agrupamento, agregação, mesclagem e remodelagem de dados de forma intuitiva.
- Tratamento de Dados Ausentes: Ferramentas eficazes para lidar com valores
NaN(Not a Number). - Integração com NumPy: Constrói sobre o NumPy, oferecendo operações vetorizadas e eficiência.
Instalação
Se você ainda não tem o Pandas instalado, pode fazê-lo facilmente via pip ou conda:
pip install pandas numpy
# ou
conda install pandas numpyÉ uma prática comum importar o Pandas com o alias pd para facilitar o uso:
import pandas as pd
import numpy as np # Também será útil para exemplos2. 📊 Pandas Series: A Estrutura Fundamental de 1 Dimensão
Uma Series do Pandas é um array unidimensional rotulado capaz de armazenar qualquer tipo de dado (inteiros, strings, floats, objetos Python, etc.). Pense nela como uma coluna de uma planilha ou uma lista Python com um índice explícito associado a cada elemento.
Definição e Analogia
- Definição: Uma
Seriesé essencialmente um array NumPy 1D com um rótulo (índice) para cada elemento. - Analogia: Uma coluna de uma tabela de banco de dados, onde cada linha tem um identificador único.
Criação de Series
Vamos ver como criar Series de diferentes maneiras, usando exemplos da documentação oficial do Pandas.
2.1. A partir de uma lista ou array NumPy
import pandas as pd
import numpy as np
# A partir de uma lista Python
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print("Series a partir de uma lista:")
print(s)
# Saída:
# 0 1.0
# 1 3.0
# 2 5.0
# 3 NaN
# 4 6.0
# 5 8.0
# dtype: float64
# A partir de um array NumPy
arr = np.array([10, 20, 30, 40])
s_np = pd.Series(arr)
print("\nSeries a partir de um array NumPy:")
print(s_np)
# Saída:
# 0 10
# 1 20
# 2 30
# 3 40
# dtype: int64Perceba que o Pandas atribui um índice numérico padrão (0, 1, 2, ...) se nenhum for fornecido.
2.2. A partir de um dicionário Python
Quando você cria uma Series a partir de um dicionário, as chaves do dicionário se tornam os rótulos do índice e os valores do dicionário se tornam os dados da Series.
data = {'a': 0., 'b': 1., 'c': 2.}
s_dict = pd.Series(data)
print("\nSeries a partir de um dicionário:")
print(s_dict)
# Saída:
# a 0.0
# b 1.0
# c 2.0
# dtype: float642.3. Com índice personalizado
Você pode especificar um índice explicitamente ao criar uma Series.
s_indexed = pd.Series([10, 20, 30], index=['x', 'y', 'z'])
print("\nSeries com índice personalizado:")
print(s_indexed)
# Saída:
# x 10
# y 20
# z 30
# dtype: int642.4. Com valor escalar
Se você passar um valor escalar e um índice, o Pandas repetirá o valor para cada elemento do índice.
s_scalar = pd.Series(5, index=['a', 'b', 'c', 'd'])
print("\nSeries com valor escalar:")
print(s_scalar)
# Saída:
# a 5
# b 5
# c 5
# d 5
# dtype: int64Atributos Importantes de uma Series
Uma Series possui vários atributos úteis para inspecionar seus dados:
.values: Retorna os dados como um array NumPy..index: Retorna o objeto de índice da Series..dtype: Retorna o tipo de dado dos elementos da Series..name: Retorna o nome da Series (útil quando é uma coluna de um DataFrame).
s = pd.Series([10, 20, 30], index=['a', 'b', 'c'], name='MinhaSerie')
print(f"\nValores (s.values): {s.values}")
print(f"Índice (s.index): {s.index}")
print(f"Tipo de dado (s.dtype): {s.dtype}")
print(f"Nome (s.name): {s.name}")
# Saída:
# Valores (s.values): [10 20 30]
# Índice (s.index): Index(['a', 'b', 'c'], dtype='object')
# Tipo de dado (s.dtype): int64
# Nome (s.name): MinhaSerieAcesso a Elementos em uma Series
Você pode acessar elementos de uma Series de duas maneiras principais:
- Indexação posicional (implícita): Usando a posição numérica (como em listas Python).
- Indexação por rótulo (explícita): Usando os rótulos definidos no índice.
s = pd.Series([100, 200, 300, 400], index=['maçã', 'banana', 'laranja', 'uva'])
# Acesso posicional (primeiro elemento)
print(f"\nPrimeiro elemento (s[0]): {s[0]}")
# Acesso por rótulo (elemento 'banana')
print(f"Elemento 'banana' (s['banana']): {s['banana']}")
# Acesso a múltiplos elementos por rótulo
print(f"Múltiplos elementos por rótulo (s[['maçã', 'uva']]):\n{s[['maçã', 'uva']]}")
# Fatiamento (slicing) posicional
print(f"Fatiamento posicional (s[1:3]):\n{s[1:3]}")
# Saída:
# Primeiro elemento (s[0]): 100
# Elemento 'banana' (s['banana']): 200
# Múltiplos elementos por rótulo (s[['maçã', 'uva']]):
# maçã 100
# uva 400
# dtype: int64
# Fatiamento posicional (s[1:3]):
# banana 200
# laranja 300
# dtype: int64Operações Básicas com Series
Series suportam operações vetorizadas, o que significa que você pode aplicar funções matemáticas a todos os elementos de uma vez, sem a necessidade de loops explícitos.
s1 = pd.Series([1, 2, 3, 4])
s2 = pd.Series([10, 20, 30, 40])
# Adição de Series (elemento a elemento)
print(f"\nAdição de Series (s1 + s2):\n{s1 + s2}")
# Multiplicação por um escalar
print(f"\nMultiplicação por escalar (s1 * 2):\n{s1 * 2}")
# Filtragem condicional
print(f"\nElementos maiores que 2 (s1[s1 > 2]):\n{s1[s1 > 2]}")
# Saída:
# Adição de Series (s1 + s2):
# 0 11
# 1 22
# 2 33
# 3 44
# dtype: int64
#
# Multiplicação por escalar (s1 * 2):
# 0 2
# 1 4
# 2 6
# 3 8
# dtype: int64
#
# Elementos maiores que 2 (s1[s1 > 2]):
# 2 3
# 3 4
# dtype: int643. 📊 Pandas DataFrame: A Estrutura Fundamental de 2 Dimensões
Um DataFrame do Pandas é uma estrutura de dados bidimensional com colunas que podem ter tipos diferentes. É a estrutura de dados mais usada no Pandas e representa uma tabela com linhas e colunas.
Definição e Analogia
- Definição: Um
DataFramepode ser pensado como uma coleção deSeriesque compartilham o mesmo índice, ou como uma tabela com linhas e colunas. - Analogia: Uma planilha Excel, uma tabela de banco de dados SQL ou um dicionário de objetos
Series.
Criação de DataFrames
Assim como as Series, DataFrames podem ser criados de várias fontes.
3.1. A partir de um dicionário de Series ou listas
Esta é uma das formas mais comuns de criar um DataFrame. As chaves do dicionário se tornam os nomes das colunas.
data = {
'coluna_A': pd.Series([1, 2, 3], index=['a', 'b', 'c']),
'coluna_B': pd.Series([4, 5, 6, 7], index=['a', 'b', 'c', 'd'])
}
df_series_dict = pd.DataFrame(data)
print("DataFrame a partir de um dicionário de Series:")
print(df_series_dict)
# Saída:
# coluna_A coluna_B
# a 1.0 4.0
# b 2.0 5.0
# c 3.0 6.0
# d NaN 7.0
# A partir de um dicionário de listas (mais comum)
data_list = {
'Nome': ['Alice', 'Bob', 'Charlie', 'David'],
'Idade': [25, 30, 35, 40],
'Cidade': ['São Paulo', 'Rio de Janeiro', 'Belo Horizonte', 'Curitiba']
}
df_list_dict = pd.DataFrame(data_list)
print("\nDataFrame a partir de um dicionário de listas:")
print(df_list_dict)
# Saída:
# Nome Idade Cidade
# 0 Alice 25 São Paulo
# 1 Bob 30 Rio de Janeiro
# 2 Charlie 35 Belo Horizonte
# 3 David 40 CuritibaObserve que, no primeiro exemplo, o Pandas alinha os dados com base nos índices das Series. Se um índice não existir em uma Series, ele preenche com NaN.
3.2. A partir de uma lista de dicionários
Cada dicionário na lista representa uma linha do DataFrame, onde as chaves são os nomes das colunas.
data_lod = [
{'Nome': 'Eva', 'Idade': 22, 'Cidade': 'Salvador'},
{'Nome': 'Frank', 'Idade': 28, 'Cidade': 'Fortaleza'},
{'Nome': 'Grace', 'Idade': 33, 'Cidade': 'Recife'}
]
df_lod = pd.DataFrame(data_lod)
print("\nDataFrame a partir de uma lista de dicionários:")
print(df_lod)
# Saída:
# Nome Idade Cidade
# 0 Eva 22 Salvador
# 1 Frank 28 Fortaleza
# 2 Grace 33 Recife3.3. A partir de um array NumPy 2D
Você pode criar um DataFrame diretamente de um array NumPy bidimensional, mas precisará fornecer os nomes das colunas e o índice das linhas.
arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
df_np = pd.DataFrame(arr_2d, columns=['Col1', 'Col2', 'Col3'], index=['Lin1', 'Lin2', 'Lin3'])
print("\nDataFrame a partir de um array NumPy 2D:")
print(df_np)
# Saída:
# Col1 Col2 Col3
# Lin1 1 2 3
# Lin2 4 5 6
# Lin3 7 8 93.4. A partir de um arquivo CSV (mencionar)
Embora não seja o foco desta aula teórica, é crucial saber que uma das formas mais comuns de carregar dados em um DataFrame é a partir de arquivos.
# df = pd.read_csv('caminho/para/seu/arquivo.csv')
# print(df.head()) # Mostra as primeiras 5 linhasAtributos Importantes de um DataFrame
Assim como Series, DataFrames possuem atributos importantes:
.index: Retorna o objeto de índice das linhas..columns: Retorna os rótulos das colunas..values: Retorna os dados como um array NumPy 2D..shape: Retorna uma tupla(número de linhas, número de colunas)..dtypes: Retorna umaSeriescom o tipo de dado de cada coluna.
df = pd.DataFrame({
'Produto': ['A', 'B', 'C', 'D'],
'Preço': [10.50, 20.00, 5.75, 12.25],
'Estoque': [100, 50, 200, 75]
})
print(f"\nÍndice (df.index): {df.index}")
print(f"Colunas (df.columns): {df.columns}")
print(f"Shape (df.shape): {df.shape}")
print(f"Tipos de dados (df.dtypes):\n{df.dtypes}")
# Saída:
# Índice (df.index): RangeIndex(start=0, stop=4, step=1)
# Colunas (df.columns): Index(['Produto', 'Preço', 'Estoque'], dtype='object')
# Shape (df.shape): (4, 3)
# Tipos de dados (df.dtypes):
# Produto object
# Preço float64
# Estoque int64
# dtype: objectAcesso a Dados em um DataFrame
A seleção de dados em um DataFrame é uma das operações mais frequentes e poderosas.
3.5. Seleção de colunas
Você pode selecionar uma ou mais colunas de um DataFrame. O resultado de uma única coluna é uma Series.
df = pd.DataFrame({
'Nome': ['Ana', 'Bruno', 'Carla'],
'Idade': [28, 34, 22],
'Salário': [50000, 60000, 45000]
})
# Selecionar uma única coluna (retorna uma Series)
print("Coluna 'Nome':")
print(df['Nome'])
# Selecionar múltiplas colunas (retorna um DataFrame)
print("\nColunas 'Nome' e 'Salário':")
print(df[['Nome', 'Salário']])
# Saída:
# Coluna 'Nome':
# 0 Ana
# 1 Bruno
# 2 Carla
# Name: Nome, dtype: object
#
# Colunas 'Nome' e 'Salário':
# Nome Salário
# 0 Ana 50000
# 1 Bruno 60000
# 2 Carla 450003.6. Seleção de linhas com .loc e .iloc
.loc: Seleciona por rótulo (label) do índice..iloc: Seleciona por posição (integer-location) do índice.
df = pd.DataFrame(
np.random.randn(6, 4),
index=pd.date_range("20230102", periods=6),
columns=list("ABCD"),
)
print("DataFrame original:")
print(df)
# Seleção de uma linha por rótulo (usando .loc)
print("\nLinha de '2023-01-03' (df.loc['2023-01-03']):")
print(df.loc['2023-01-03'])
# Seleção de linhas por rótulo (fatiamento com .loc)
print("\nLinhas de '2023-01-02' a '2023-01-04' (df.loc['2023-01-02':'2023-01-04']):")
print(df.loc['2023-01-02':'2023-01-04'])
# Seleção de linhas por posição (usando .iloc)
print("\nPrimeira linha (df.iloc[0]):")
print(df.iloc[0])
# Seleção de linhas e colunas por posição (df.iloc[0:2, 1:3])
print("\nPrimeiras 2 linhas e colunas 1 e 2 (df.iloc[0:2, 1:3]):")
print(df.iloc[0:2, 1:3])(A saída do código acima irá variar devido ao np.random.randn)
3.7. Filtragem condicional
Você pode filtrar linhas com base em condições lógicas aplicadas às colunas.
df = pd.DataFrame({
'Produto': ['A', 'B', 'C', 'D'],
'Preço': [10.50, 20.00, 5.75, 12.25],
'Estoque': [100, 50, 200, 75]
})
# Filtrar produtos com preço maior que 10
df_caros = df[df['Preço'] > 10]
print("\nProdutos com Preço > 10:")
print(df_caros)
# Filtrar produtos com estoque menor que 100 E preço menor que 20
df_especificos = df[(df['Estoque'] < 100) & (df['Preço'] < 20)]
print("\nProdutos com Estoque < 100 E Preço < 20:")
print(df_especificos)
# Saída:
# Produtos com Preço > 10:
# Produto Preço Estoque
# 0 A 10.50 100
# 1 B 20.00 50
# 3 D 12.25 75
#
# Produtos com Estoque < 100 E Preço < 20:
# Produto Preço Estoque
# 3 D 12.25 75Operações Básicas com DataFrames
DataFrames permitem uma vasta gama de operações.
3.8. Adicionar/remover colunas
df = pd.DataFrame({
'Nome': ['Pedro', 'Maria'],
'Idade': [29, 31]
})
# Adicionar uma nova coluna
df['Gênero'] = ['M', 'F']
print("\nDataFrame com coluna 'Gênero' adicionada:")
print(df)
# Adicionar uma coluna calculada
df['Idade_x_2'] = df['Idade'] * 2
print("\nDataFrame com coluna 'Idade_x_2' adicionada:")
print(df)
# Remover uma coluna
df_sem_idade_x_2 = df.drop(columns=['Idade_x_2'])
print("\nDataFrame com coluna 'Idade_x_2' removida:")
print(df_sem_idade_x_2)
# Saída:
# DataFrame com coluna 'Gênero' adicionada:
# Nome Idade Gênero
# 0 Pedro 29 M
# 1 Maria 31 F
#
# DataFrame com coluna 'Idade_x_2' adicionada:
# Nome Idade Gênero Idade_x_2
# 0 Pedro 29 M 58
# 1 Maria 31 F 62
#
# DataFrame com coluna 'Idade_x_2' removida:
# Nome Idade Gênero
# 0 Pedro 29 M
# 1 Maria 31 F3.9. Operações vetorizadas entre colunas
Assim como nas Series, você pode realizar operações matemáticas entre colunas de um DataFrame.
df = pd.DataFrame({
'Vendas': [100, 150, 200],
'Custos': [50, 70, 90]
})
df['Lucro'] = df['Vendas'] - df['Custos']
print("\nDataFrame com coluna 'Lucro' calculada:")
print(df)
# Saída:
# DataFrame com coluna 'Lucro' calculada:
# Vendas Custos Lucro
# 0 100 50 50
# 1 150 70 80
# 2 200 90 1104. 📝 Resumo e Próximos Passos
Parabéns! 🎉 Você deu os primeiros passos essenciais no mundo do Pandas.
Resumo
- Pandas é a biblioteca fundamental para manipulação de dados em Python.
- Series são estruturas de dados unidimensionais rotuladas, como uma coluna de dados.
- DataFrames são estruturas de dados bidimensionais, como uma tabela, compostas por uma coleção de
Seriesque compartilham o mesmo índice. - Ambas as estruturas oferecem poderosas ferramentas de criação, inspeção e acesso a dados.
- As operações são vetorizadas, tornando o trabalho com grandes volumes de dados eficiente.
Próximos Passos
Esta aula cobriu apenas a ponta do iceberg do que o Pandas pode fazer. Para continuar sua jornada, explore os seguintes tópicos:
- Leitura e Escrita de Dados: Aprenda a carregar dados de arquivos CSV, Excel, SQL e outros formatos usando
pd.read_csv(),pd.read_excel(), etc. - Limpeza de Dados: Descubra como lidar com valores ausentes (
NaN), duplicados e formatos incorretos. - Agregação e Agrupamento: Explore
groupby()para resumir dados por categorias. - Mesclagem e Concatenação: Aprenda a combinar
DataFramesusandopd.merge()epd.concat(). - Visualização de Dados: Integre o Pandas com bibliotecas como Matplotlib e Seaborn para criar gráficos informativos.
Continue praticando e explorando a documentação oficial do Pandas. Ela é uma fonte rica de informações e exemplos!
Até a próxima aula! 👋