Introdução
O Guia do Analista de Dados fornece tanto os conceitos quanto os exemplos necessários para que você, como analista de dados, possa começar a se aventurar na busca pela informação. Destacamos ainda boas práticas que, se seguidas corretamente, tornam a vida de todo o seu time muito mais fácil.
Caso você já tenha um pouco de experiência e esteja apenas com alguma dificuldade específica em relação à sua tarefa, o guia de referência e os exemplos são ótimos companheiros para consultar e auxiliar na resolução do seu problema.
Objetivo
Esse guia foi criado com a intenção de ajudar os meus colegas de trabalho a entender e aplicar as melhores práticas do mercado de ciência de dados. Nosso trabalho envolve a constante automatização de processos de ETL, e um guia como esse facilita a integração de novos membros ao time.
Nota do Autor
Por favor, utilize este guia como uma referência. Garanto que você não vai utilizar o conhecimento de todos os tópicos ao mesmo tempo para resolver um único problema. Seja pragmático, focando em resolver a sua tarefa atual e aproveitando o conhecimento disposto aqui para esse fim.
Processo de ETL
Extração
Esta página ainda está sendo construída. Se quiser contribuir com o guia, acesse o nosso repositório.
A etapa de extração de dados envolve buscar os dados brutos diretamente de suas fontes, podendo agregá-los em uma área intermediária para a etapa de transformação. Ela pode ser realizada de diversas formas diferentes, mas nós lidamos primariamente com web scraping e arquivos estruturados compartilhados dentro da organização.
Note que, quando falamos de área intermediária, se refere a qualquer lugar onde o dado é armazenado temporariamente para que possa ser transformado. Alguns exemplos são: em memória, banco de dados (local ou remoto) e sistema de arquivos.
A extração pode ser categorizada como:
Notificação
A extração visando a notificação é a mais simples forma de extração de dados. Ela apenas verifica se houve uma atualização dos dados brutos na fonte e envia uma alerta para um sistema de notificações. Também é possível configurar algumas fontes para que elas enviem essa notificação de forma automática.
Esse tipo de extração é interessante por consumir bem menos recursos, já que geralmente não é necessário interagir com a área intermediária nela.
Exemplos
- Conexão via webhook à fonte para receber alertas automaticamente
- Assinatura em uma newsletter que anuncie quando houverem atualizações dos dados
- Leitura periódica à fonte de dados para verificar se houveram alterações (geralmente via crawler ou agente)
Gradual
A extração gradual é aquela que visa obter apenas os dados que sofreram alterações em um determinado período. Fica subentendido que foi executada uma extração completa para construir a base de dados em um primeiro momento, e as extrações graduais apenas vão atualizando os dados conforme necessário.
Essa forma de extrair dados tem que interagir com a área intermediária, acrescentando os dados coletados nela. Ela é mais eficiente do que executar extrações completas quando houver atualização de dados, não precisando sobrescrever dados já coletados que não sofreram alterações.
Exemplos
- Consulta de novos relatórios do SICONFI a cada bimestre/quadrimestre
Completa
A extração completa coleta todos os dados, independente de terem sido alterados ou não, a fim de carregá-los na área intermediária. Essa operação costuma ser mais custosa conforme o volume de dados aumenta.
Exemplos
- Coleta do arquivo CSV das emendas parlamentares individuais e de bancada do Tesouro Nacional, onde os dados são acrescentados ao final do arquivo periodicamente
CSV
Esta página ainda está sendo construída. Se quiser contribuir com o guia, acesse o nosso repositório.
O CSV (Comma-Separated Values) é um dos formatos mais simples para representar dados estruturados, por isso é uma extensão de arquivo comum para planilhas. É importante entender a extensão de forma compreensiva, pois ela é amplamente utilizada no contexto de dados. Discutiremos então elementos como sua estrutura e suas peculiaridades.
Estrutura
Um arquivo CSV qualquer geralmente tem esse formato:
Nome,Idade,CorPreferida
João,20,Verde
Maria,21,Amarelo
Nesse exemplo, podemos observar alguns elementos fundamentais:
- Cabeçalho:
Nome,IdadeeCorPreferidasão o cabeçalho (header) desse arquivo CSV. É importante notar que nem sempre o cabeçalho vai estar presente, podendo estar em um arquivo separado chamado Dicionário de Dados; - Valores: os valores são aqueles separados por um separador, nesse caso a vírgula, como o próprio nome CSV indica. Eles podem ou não estar encapsulados, geralmente por aspas (‘simples’ ou “duplas”);
Assim, cada linha em um arquivo CSV trata de um conjunto de valores separados por um separador.
Separadores
Separadores ou Delimitadores são caracteres ou padrões usados no arquivo CSV
para separar os valores de uma linha. O separador padrão é a , (vírgula),
mas outros comumente encontrados são a | (barra vertical) e o ; (ponto
e vírgula).
Mas o que acontece quando um valor contém o separador?
Se você tem uma coluna Descrição, por exemplo, com um valor de mesmo assim, seguimos, você não pode simplesmente usá-lo no arquivo CSV com o separador
,, senão a linha vai resultar em um erro na hora da leitura. Para evitar isso,
temos duas opções:
- usar um separador diferente e incomum para separar os valores, como o
|; - encapsular os valores que contém o separador em aspas simples ou duplas;
O mais recomendado é encapsular o valor em aspas, caso necessário, porque mesmo separadores incomuns ainda podem resultar em erros.
Codificação (Encoding)
O Encoding trata da representação em bytes dos caracteres. Isso influencia
como o arquivo deve ser lido pelas aplicações. Para maiores informações,
recomendamos a leitura desse artigo.
O encoding mais comum para arquivos CSV é o UTF-8, que suporta caracteres da
gigantesca maioria das línguas e símbolos (como emojis).
É importante sempre estar ciente do encoding utilizado pelo arquivo que você queira manipular, pois utilizar o errado é como tentar destrancar uma porta com a chave de outra. O pior mesmo é quando achamos que o encoding é o correto até descobrirmos uma série de ??? ou ���.
Para checar o encoding de um arquivo podemos usar o seguinte comando no Windows, Linux ou MacOS:
file ARQUIVO
A saída esperada terá esse formato:
ARQUIVO: encoding
Peculiaridades
Como arquivos CSV são muito flexíveis em suas estruturas, há muitas formas diferentes de representá-los. Algumas dessas formas são inerentes a programas específicos, como é o caso do Byte Order Mark (BOM). Em geral, é recomendado sempre tentar adotar normas como a RFC 4180.
Byte order mark (BOM)
Em arquivos CSV gerados pelo Microsoft Excel, é comum o uso de uma pequena sequência de bytes no início do arquivo, indicando o seu encoding. O nome dessa sequência é BOM (Byte Order Mark). Se você utiliza o Excel para manipular arquivos CSV e pretende compartilhar eles com alguém, faça um favor a todos nós e opte por não usar o BOM ao salvar o arquivo.
Caso você queira saber se um arquivo CSV contém BOM, o comando mostrado na seção
de Codificação indica a sua presença por meio do texto
(with BOM).
Arquivos .csv.zip
Arquivos CSV comprimidos são um indicador de que ele será um arquivo volumoso (1+ GB). São necessárias técnicas específicas para lidar com esse tipo de arquivo, como streaming, principalmente porque a memória do seu computador é limitada. Em ambientes Linux, recomendamos usar as técnicas descritas aqui.
É possível também utilizar uma abordagem mais universal por meio da biblioteca padrão do Python, como mostrado abaixo:
import io
import pandas as pd
from zipfile import ZipFile
zip_path = 'NOME_DO_ARQUIVO.csv.zip'
member_name = None
with ZipFile(zip_path) as z:
member_name = z.namelist()[0]
with z.open(member_name, 'r') as fbytes:
# Alguns detalhes sobre o TextIOWrapper:
# - Utilize encoding='utf-8-sig' caso o arquivo CSV contenha um BOM
# - Utilize errors='replace' se você não se importa com dados
# potencialmente corrompidos
text_stream = io.TextIOWrapper(fbytes, encoding='utf-8', errors='replace')
# Abaixo, temos a leitura do arquivo em partes (chunks), por meio do
# parâmetro chunksize. Esse parâmetro determina quantas linhas são lidas
# de cada vez, e deve ser ajustado considerando a memória disponível e o
# volume esperado de dados por linha. Um bom indicador do volume de
# dados de uma linha é o número de colunas do CSV. Via de regra, quanto
# mais colunas, menor deve ser o chunksize para ambientes de baixa
# memória.
chunks = pd.read_csv(
text_stream,
sep=",", # Indica qual separador o CSV utiliza
chunksize=1000, # Número de linhas lidas por iteração
)
for i, chunk in enumerate(chunks):
# Realize as manipulações dos dados aqui
Extração
Esta página ainda está sendo construída. Se quiser contribuir com o guia, acesse o nosso repositório.
Consumo de Arquivos CSV
Arquivos CSV são compatíveis com diversos softwares de leitura de planilha,
como Microsoft Excel e LibreOffice Calc. Porém, quando trabalhamos com
automação, temos que manipular os arquivos através de código, usando bibliotecas
como pandas e polars. Assim, temos alguns comandos básicos abaixo:
Abrir o Arquivo CSV como DataFrame, Mostrando Suas Primeiras Linhas
import pandas as pd
df = pd.read_csv("arquivo.csv")
print(df.head())
Filtrar Colunas Específicas de um DataFrame
cols = [
"id",
"nome",
"host_id",
"bairro",
"tipo_de_quarto",
"preco",
"estadia_minima",
]
hotel_data = pd.read_csv(
"hotel_data.csv",
usecols=cols,
)
Outras Parâmetros de Leitura do Arquivo
# Declara o separador usado para ler os dados do CSV (O separador padrão é a
# vírgula)
pd.read_csv("data.csv", sep=";")
# Declara a linha que será utilizada como cabeçalho do DataFrame (A linha padrão
# é a primeira)
pd.read_csv("data.csv", header=3)
# Declara o tipo dos dados nas colunas do DataFrame. Não é aconselhável utilizar
# os tipos padrão do Python, como int ou float, mas sim os tipos anuláveis
# (nullable) indicados na documentação do pandas, como "Int64" e "Float64"
pd.read_csv("data.csv", dtype={
"id": "Int64",
"price": "Float64",
})
Transformação
Esta página ainda está sendo construída. Se quiser contribuir com o guia, acesse o nosso repositório.
Métodos e Atributos da Estrutura de DataFrame
Um DataFrame é uma estrutura de dados que organiza dados em uma tabela
bidimensional de linhas e colunas, similar a uma planilha. Essa é a estrutura de
dados mais comum usada na manipulação dos dados, geralmente utilizando pandas.
Alguns métodos descritivos sobre os dados de um DataFrame pandas são
apresentados abaixo:
import pandas as pd
df = pd.read_csv("dados.csv")
# Mostrar colunas disponíveis no DataFrame
print(df.columns)
# Mostrar resumo dos dados, como número de colunas, tipos de dados, etc. no DataFrame
print(data.info())
# Mostrar uma descrição estatística dos dados no DataFrame
print(data.describe())
Como Lidar com Datasets Grandes
Como os computadores atuais têm um limite de memória muito baixo, entre 8 GB e 32 GB, geralmente. Quando lidamos com arquivos de dezenas de GB ou até TB, é inviável simplesmente carregá-los na memória, tanto pelo consumo de recursos, quanto pelo tempo necessário para realizar as operações.
Dessa forma, é importante aplicar os conceitos de streaming e sharding para ou consumir os dados aos poucos ou filtrá-los o máximo possível antes de carregá-los na memória (ainda assim, sem garantias de que os dados filtrados não terão um volume absurdo).
A biblioteca pandas fornece algumas maneiras de lidar com esse problema, por
meio do parâmetro chunksize, que lê $n$ linhas por vez de um arquivo. Isso
permite trabalhar com múltiplos DataFrames, cada um trazendo uma parcela dos
dados.
Importando um Dataset Grande
import pandas as pd
for chunk in pd.read_csv(
"dados.csv",
chunksize=1000, # Representa a quantidade de linhas por chunk
):
# Realize suas manipulações aqui, considerando o chunk como um DataFrame com
# a mesma estrutura do arquivo "dados.csv"
Contribuidores
- Eduardo Henrique Freire Machado
- [Luiz Gustavo Dall’Agnol Cavalcante]