Manipulação de dados com Pandas em Python

1. Introdução ao Pandas e Estruturas de Dados Fundamentais

Pandas é a biblioteca mais importante para manipulação e análise de dados em Python. Desenvolvida por Wes McKinney em 2008, ela oferece estruturas de dados poderosas e flexíveis que tornam o trabalho com dados tabulares e temporais muito mais eficiente do que usar listas e dicionários nativos.

As duas estruturas fundamentais do Pandas são:

Series: vetor unidimensional rotulado, similar a uma coluna em uma planilha. Cada elemento possui um índice associado.

DataFrame: tabela bidimensional com linhas e colunas rotuladas, equivalente a uma planilha ou tabela SQL.

Para instalar e importar o Pandas:

pip install pandas
import pandas as pd
import numpy as np

Criando estruturas básicas:

# Criando uma Series
series_exemplo = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
print(series_exemplo)

# Criando um DataFrame
dados = {
    'Nome': ['Ana', 'Bruno', 'Carla', 'Daniel'],
    'Idade': [25, 32, 28, 35],
    'Salario': [5000, 7000, 6200, 8500]
}
df = pd.DataFrame(dados)
print(df)

2. Carregamento e Exportação de Dados

Pandas oferece funções especializadas para ler e escrever dados em diversos formatos. Os mais comuns são CSV, Excel, JSON e SQL.

# Leitura de arquivo CSV
df_csv = pd.read_csv('vendas.csv', sep=',', encoding='utf-8')

# Leitura com parâmetros avançados
df_csv = pd.read_csv(
    'dados.csv',
    sep=';',
    encoding='latin1',
    header=0,
    dtype={'coluna1': str, 'coluna2': float},
    parse_dates=['data']
)

# Leitura de Excel
df_excel = pd.read_excel('relatorio.xlsx', sheet_name='Vendas')

# Leitura de JSON
df_json = pd.read_json('dados.json')

# Exportação
df.to_csv('exportado.csv', index=False)
df.to_excel('exportado.xlsx', sheet_name='Dados')
df.to_json('exportado.json', orient='records')

Para grandes volumes, use chunks:

chunks = pd.read_csv('grande_arquivo.csv', chunksize=10000)
for chunk in chunks:
    processar(chunk)

3. Seleção, Filtragem e Indexação de Dados

A seleção precisa de dados é essencial. Pandas oferece múltiplas formas de acessar elementos específicos.

# Seleção por rótulo com loc
df.loc[0:2, 'Nome':'Salario']

# Seleção por posição com iloc
df.iloc[0:3, 0:2]

# Filtragem condicional
filtro = df[df['Idade'] > 30]
print(filtro)

# Filtros complexos com operadores booleanos
filtro_composto = df[(df['Idade'] > 25) & (df['Salario'] < 8000)]
print(filtro_composto)

# Usando query para filtros legíveis
filtro_query = df.query('Idade > 25 and Salario < 8000')
print(filtro_query)

# Indexação hierárquica (MultiIndex)
arrays = [['A', 'A', 'B', 'B'], [1, 2, 1, 2]]
multi_index = pd.MultiIndex.from_arrays(arrays, names=['grupo', 'sub'])
df_multi = pd.DataFrame({'valor': [10, 20, 30, 40]}, index=multi_index)
print(df_multi)

4. Limpeza e Tratamento de Dados Ausentes

Dados reais raramente estão completos. Pandas fornece ferramentas robustas para lidar com valores ausentes.

# Criando dados com valores nulos
df_sujo = pd.DataFrame({
    'A': [1, 2, None, 4],
    'B': [None, 2, 3, 4],
    'C': [1, None, None, 4]
})

# Identificando valores nulos
print(df_sujo.isna())
print(df_sujo.isnull().sum())

# Removendo linhas com valores nulos
df_limpo = df_sujo.dropna()
print(df_limpo)

# Removendo colunas com muitos nulos
df_limpo_colunas = df_sujo.dropna(axis=1, thresh=3)

# Preenchendo valores ausentes
df_preenchido = df_sujo.fillna(0)
df_preenchido_media = df_sujo.fillna(df_sujo.mean())

# Interpolação para séries temporais
serie_temporal = pd.Series([1, None, None, 4, None, 6])
serie_interpolada = serie_temporal.interpolate()
print(serie_interpolada)

# Removendo duplicatas
df_com_duplicatas = pd.DataFrame({'A': [1, 1, 2, 2], 'B': [10, 10, 20, 20]})
df_sem_duplicatas = df_com_duplicatas.drop_duplicates()
print(df_sem_duplicatas)

5. Transformação e Manipulação de Colunas

Criar e modificar colunas é uma operação frequente na preparação de dados.

# Criando novas colunas com operações vetorizadas
df['Bonus'] = df['Salario'] * 0.1
df['Salario_Total'] = df['Salario'] + df['Bonus']

# Aplicando funções com apply
df['Faixa_Etaria'] = df['Idade'].apply(lambda x: 'Jovem' if x < 30 else 'Adulto')

# Usando map para substituições
mapeamento = {25: 'Vinte e cinco', 32: 'Trinta e dois'}
df['Idade_Extenso'] = df['Idade'].map(mapeamento)

# Renomeando colunas
df_renomeado = df.rename(columns={'Nome': 'Nome_Completo', 'Idade': 'Anos'})

# Reordenando colunas
df_reordenado = df[['Salario', 'Nome', 'Idade']]

# Convertendo tipos de dados
df['Idade'] = df['Idade'].astype(float)
df['Data'] = pd.to_datetime(['2023-01-01', '2023-02-15', '2023-03-20', '2023-04-10'])

6. Agrupamento e Agregação de Dados

O GroupBy é uma das funcionalidades mais poderosas do Pandas, permitindo análises segmentadas.

# Dados de exemplo para agrupamento
vendas = pd.DataFrame({
    'Produto': ['A', 'B', 'A', 'B', 'A', 'C'],
    'Quantidade': [10, 20, 15, 25, 12, 30],
    'Valor': [100, 200, 150, 250, 120, 300],
    'Regiao': ['Norte', 'Sul', 'Norte', 'Sul', 'Norte', 'Norte']
})

# GroupBy básico
grupo_produto = vendas.groupby('Produto')
print(grupo_produto['Valor'].sum())

# Múltiplas agregações
agregacoes = vendas.groupby('Produto').agg({
    'Quantidade': ['sum', 'mean'],
    'Valor': ['sum', 'mean', 'count']
})
print(agregacoes)

# Agregação personalizada
def intervalo(valores):
    return valores.max() - valores.min()

personalizado = vendas.groupby('Regiao')['Valor'].agg(intervalo)

# Tabela dinâmica com pivot_table
pivot = pd.pivot_table(
    vendas,
    values='Valor',
    index='Produto',
    columns='Regiao',
    aggfunc='sum',
    fill_value=0
)
print(pivot)

# Operações de janela (rolling)
serie = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
media_movel = serie.rolling(window=3).mean()
print(media_movel)

7. Combinação e Junção de DataFrames

Combinar dados de múltiplas fontes é uma necessidade comum. Pandas oferece concat e merge para isso.

# Concatenação vertical
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
concatenado_vertical = pd.concat([df1, df2], ignore_index=True)
print(concatenado_vertical)

# Concatenação horizontal
concatenado_horizontal = pd.concat([df1, df2], axis=1)

# Merge (join SQL)
clientes = pd.DataFrame({
    'id_cliente': [1, 2, 3],
    'nome': ['Ana', 'Bruno', 'Carla']
})
pedidos = pd.DataFrame({
    'id_cliente': [1, 2, 4],
    'produto': ['Notebook', 'Mouse', 'Teclado'],
    'valor': [3000, 150, 200]
})

# Inner join
inner_join = pd.merge(clientes, pedidos, on='id_cliente', how='inner')
print(inner_join)

# Left join
left_join = pd.merge(clientes, pedidos, on='id_cliente', how='left')

# Outer join
outer_join = pd.merge(clientes, pedidos, on='id_cliente', how='outer')

# Join baseado em índice
clientes_index = clientes.set_index('id_cliente')
pedidos_index = pedidos.set_index('id_cliente')
join_por_indice = clientes_index.join(pedidos_index, lsuffix='_cliente', rsuffix='_pedido')

8. Visualização Rápida e Análise Exploratória

Pandas integra-se diretamente com Matplotlib para visualizações rápidas, além de oferecer estatísticas descritivas.

# Estatísticas descritivas
print(df.describe())
print(df.info())
print(df.describe(include='all'))

# Correlação entre variáveis
correlacao = df.corr()
print(correlacao)

# Gráfico de linhas
df['Salario'].plot(kind='line', title='Evolução dos Salários')

# Gráfico de barras
df.groupby('Nome')['Salario'].sum().plot(kind='bar', title='Salário por Pessoa')

# Histograma
df['Idade'].plot(kind='hist', bins=5, title='Distribuição de Idades')

# Boxplot para detecção de outliers
df.boxplot(column=['Salario'])

# Exportação de resultados
resumo = df.describe()
resumo.to_csv('resumo_estatistico.csv')

# Relatório simples
with open('relatorio.txt', 'w') as f:
    f.write("RELATÓRIO DE ANÁLISE\n")
    f.write("="*50 + "\n")
    f.write(f"Total de registros: {len(df)}\n")
    f.write(f"Média salarial: R$ {df['Salario'].mean():.2f}\n")
    f.write(f"Idade média: {df['Idade'].mean():.1f} anos\n")

Pandas é uma ferramenta indispensável para qualquer profissional que trabalhe com dados em Python. Sua combinação de estruturas flexíveis, métodos otimizados e integração com outras bibliotecas do ecossistema científico (NumPy, Matplotlib, Scikit-learn) torna a manipulação de dados eficiente e produtiva. Dominar estas técnicas é fundamental para análise exploratória, preparação de dados para machine learning e geração de relatórios automatizados.

Referências