Buscar

ED0501_LimpezaTransformaçãoEEnriquecimentoDeDados

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 66 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 66 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 66 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Prof. Giovane Barcelos 
giovane_barcelos@uniritter.edu.br 
Engenharia de Dados
ED0501
mailto:giovane_barcelos@uniritter.edu.br
Pág. 2 Engenharia de Dados De 66
Plano de Ensino
Conteúdo programático
N2N2
N1N1
1. Construindo os pipelines de dados: extrair, transformar e carregar
1.1 O que é engenharia de dados? (a)
1.2 Construindo nossa infraestrutura de engenharia de dados (b)
1.3 Leitura e gravação de arquivos
1.4 Trabalhando com bancos de dados (c, d)
1.5 Limpeza, transformação e enriquecimento de dados
1.6 Construindo o pipeline de dados (h)
2. Implantação de pipelines de dados na produção
2.1 Recursos de um pipeline em produção (f, g)
2.2 Controle de versão com o NiFi Registry (e)
2.3 Monitorando pipelines de dados
2.4 Implantando pipelines de dados
2.5 Construindo um pipeline de dados em produção (i)
3 Além do Lote (batch) - criando pipelines de dados em tempo real
3.1 Construindo um cluster Kafka (b)
3.2 Streaming de dados com Apache Kafka (e)
3.3 Processamento de dados com Apache Spark (e)
3.4 Dados de borda (edge) em tempo real com MiNiFi, Kafka e Spark
3.5 Construção, implantação e gerenciamento de pipelines: uma revisão geral
Pág. 3 Engenharia de Dados De 66
➢ Anteriormente aprendemos como construir pipelines de dados que 
podiam ler e gravar em arquivos e bancos de dados
➢ Em muitos casos, essas habilidades por si só permitirão que você crie 
pipelines de dados de produção
➢ Por exemplo, você lerá arquivos de um data lake e os inserirá em um 
banco de dados
➢ Às vezes, no entanto, você precisará fazer algo com os dados após a 
extração, mas antes do carregamento
➢ O que você precisa fazer é limpar os dados. Limpeza é um termo vago.
➢ Mais especificamente, você precisará verificar a validade dos dados e 
responder a perguntas como as seguintes: 
✔ Está completo? 
✔ Os valores estão dentro dos intervalos adequados? 
✔ As colunas são do tipo adequado? 
✔ Todas as colunas são úteis?
Limpeza, Transformação e Enriquecimento de Dados
O que significa limpar, transformar e enriquecer os dados?
Pág. 4 Engenharia de Dados De 66
➢ Execução de análise exploratória de dados em Python
➢ Lidar com problemas comuns de dados usando o pandas
➢ Limpeza de dados usando o Airflow
Limpeza, Transformação e Enriquecimento de Dados
O que vamos aprender?
Pág. 5 Engenharia de Dados De 66
➢ Antes de limpar seus dados, você precisa saber como eles se parecem
➢ Como engenheiro de dados, você não é o especialista no domínio e não é 
o usuário final dos dados, mas deve saber para que os dados serão 
usados e como seriam os dados válidos
➢ Por exemplo, você não precisa ser um demógrafo para saber que um 
campo de idade não deve ser negativo e a frequência de valores acima 
de 100 será baixa
Limpeza, Transformação e Enriquecimento de Dados
Executando análise exploratória de dados em Python
Pág. 6 Engenharia de Dados De 66
➢ Vamos utilizar dados reais de e-scooters (patinetes) da cidade de 
Albuquerque
➢ Os dados contêm viagens feitas com e-scooters em 22/06/2019
➢ Você precisará baixar os dados dos e-scooters em 
https://github.com/giovanebarcelos/ED20212/blob/main/datasets/scooter.csv
Limpeza, Transformação e Enriquecimento de Dados
Baixando os dados
https://github.com/giovanebarcelos/ED20212/blob/main/datasets/scooter.csv
Pág. 7 Engenharia de Dados De 66
➢ Antes de limpar seus dados, você precisa saber como eles se parecem
➢ O processo de compreensão de seus dados é chamado de análise 
exploratória de dados
➢ Você observará a forma de seus dados, o número de linhas e colunas, 
bem como os tipos de dados nas colunas e os intervalos de valores
➢ Pode realizar uma análise muito mais aprofundada, como a distribuição 
dos dados ou a assimetria
➢ Para começar, precisamos importar com o pandas e ler o arquivo .csv:
import pandas as pd
df=pd.read_csv('scooter.csv')
➢ Com os dados em um DataFrame, agora podemos explorá-los e, em 
seguida, analisá-los
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 8 Engenharia de Dados De 66
➢ Agora você pode começar a examinar os dados
➢ A primeira coisa que você provavelmente desejará fazer é imprimi-lo
➢ Mas antes de chegar a isso, dê uma olhada nas colunas e nos tipos de 
dados usando columns e dtypes:
Limpeza, Transformação e Enriquecimento de Dados
Explorando os dados
>>> df.columns
Index(['month', 'trip_id', 'region_id',
 'vehicle_id', 'started_at', 'ended_at',
 'DURATION', 'start_location_name',
 'end_location_name', 'user_id',
 'trip_ledger_id'],
 dtype='object')
>>> df.dtypes
month object
trip_id int64
region_id int64
vehicle_id int64
started_at object
ended_at object
DURATION object
start_location_name object
end_location_name object
user_id int64
trip_ledger_id int64
dtype: object
Pág. 9 Engenharia de Dados De 66
➢ Você verá que tem onze colunas, cinco das quais são inteiros (todas as 
colunas com ID em seus nomes) e as demais são objetos
➢ Objetos são o que um DataFrame usa como dtype quando há tipos 
mistos
➢ Além disso, DURATION deve se destacar por ser o único nome de coluna 
em maiúsculas
➢ Em seguida corrigiremos os erros comuns, como os casos das colunas 
não são uniformes (todas em minúsculas ou maiúsculas) e fará com que 
os tipos de objeto dtypes sejam os tipos adequados, como strings para 
dados de texto e datetimes para datas e horas
➢ Agora que você sabe o que tem de colunas e tipos, vamos examinar os 
dados. Você pode imprimir os primeiros cinco registros usando head():
 df.head()
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 10 Engenharia de Dados De 66
➢ O oposto de head() é tail()
➢ Ambos os métodos padrão mostram 5 linhas
➢ No entanto, você pode passar um número inteiro como um parâmetro 
que especifica quantas linhas mostrar
➢ Por exemplo, você pode passar o head(10) para ver as primeiras 10 
linhas
➢ Observe na saída head() e tail() que a terceira coluna é ..., e há mais 
duas colunas depois disso
➢ A tela está cortando as colunas do meio
➢ Se você fosse imprimir todo o DataFrame, a mesma coisa aconteceria 
com as linhas também
➢ Para exibir todas as colunas, você pode alterar o número de colunas a 
serem mostradas usando o método set_options:
 pd.set_option('display.max_columns', 500)
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 11 Engenharia de Dados De 66
➢ Os métodos head e tail exibem todas as colunas, mas se você estiver interessado 
apenas em uma única coluna, poderá especificá-la como faria em um dicionário 
Python
➢ O código a seguir imprime a coluna DURATION:
>>> df['DURATION']
0 0:07:03
1 0:04:57
2 0:01:14
3 0:06:58
4 0:03:06
 ... 
34221 0:14:00
34222 0:08:00
34223 1:53:00
34224 0:12:00
34225 1:51:00
Name: DURATION, Length: 34226, dtype: object
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 12 Engenharia de Dados De 66
➢ Assim como você pode exibir uma única coluna, você pode exibir uma lista de 
colunas usando double [], conforme mostrado no seguinte bloco de código:
>>> df[['trip_id','DURATION','start_location_name']]
 trip_id DURATION start_location_name
0 1613335 0:07:03 1901 Roma Ave NE, Albuquerque, NM 87106, USA
1 1613639 0:04:57 1 Domenici Center en Domenici Center, Albuquer...
2 1613708 0:01:14 1 Domenici Center en Domenici Center, Albuquer...
3 1613867 0:06:58 Rotunda at Science & Technology Park, 801 Univ...
4 1636714 0:03:06 401 2nd St NW, Albuquerque, NM 87102, USA
... ... ... ...
34221 2482235 0:14:00 Central @ Broadway, Albuquerque, NM 87102, USA
34222 24822540:08:00 224 Central Ave SW, Albuquerque, NM 87102, USA
34223 2482257 1:53:00 105 Stanford Dr SE, Albuquerque, NM 87106, USA
34224 2482275 0:12:00 100 Broadway Blvd SE, Albuquerque, NM 87102, USA
34225 2482335 1:51:00 105 Stanford Dr SE, Albuquerque, NM 87106, USA
[34226 rows x 3 columns]
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 13 Engenharia de Dados De 66
➢ Você também pode extrair uma amostra de seus dados usando sample()
➢ Os métodos de amostra permitem que você especifique quantas linhas 
deseja extrair
➢ Os resultados são mostrados no seguinte bloco de código:
>>> df.sample(5)
 month trip_id region_id ... end_location_name user_id trip_ledger_id
9906 June 1834177 202 ... 413 2nd St SW, Albuquerque, NM 87102, USA 35920330 1702781
11381 June 1858309 202 ... 1720 Central Ave SW, Albuquerque, NM 87104, USA 36647277 1725629
28090 July 2265900 202 ... 2101 Mountain Rd NW, Albuquerque, NM 87104, USA 42440628 2123432
32020 July 2396678 202 ... NaN 42227670 2256679
8006 June 1804406 202 ... 330 Tijeras Ave NW, Albuquerque, NM 87102, USA 37175121 1673778
[5 rows x 11 columns]
➢ Observe que o índice das linhas não é incremental, mas sim salta, pois é 
uma amostra
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 14 Engenharia de Dados De 66
➢ Você também pode dividir os dados
➢ O fatiamento assume o formato de [início: fim], onde um espaço em 
branco é a primeira ou a última linha, dependendo de qual posição está 
em branco
➢ Para fatiar as primeiras 3 linhas, você pode usar a seguinte notação:
>>> df[:3]
 month trip_id region_id ... user_id trip_ledger_id
0 May 1613335 202 ... 8417864 1488546
1 May 1613639 202 ... 8417864 1488838
2 May 1613708 202 ... 8417864 1488851
➢ Da mesma forma, para pegar as linhas de 10 ao final (34.225), você 
pode usar a seguinte notação:
df[10:]
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 15 Engenharia de Dados De 66
➢ Você também pode fatiar o quadro começando na terceira linha e 
terminando antes da sexta, conforme mostrado no seguinte bloco de 
código:
>>> df[3:6]
 month trip_id region_id ... user_id trip_ledger_id
3 May 1613867 202 ... 8417864 1489064
4 May 1636714 202 ... 35436274 1511212
5 May 1636780 202 ... 34352757 1511371
[3 rows x 11 columns]
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 16 Engenharia de Dados De 66
➢ Às vezes, você sabe a linha exata que deseja e, em vez de fatiá-la, pode 
selecioná-la usando loc()
➢ O método loc leva o nome do índice, que, neste exemplo, é um inteiro
➢ O código e a saída a seguir mostram uma única linha selecionada com loc():
>>> df.loc[34221]
month July
trip_id 2482235
region_id 202
vehicle_id 2893981
started_at 7/21/2019 23:51
ended_at 7/22/2019 0:05
DURATION 0:14:00
start_location_name Central @ Broadway, Albuquerque, NM 87102, USA
end_location_name 1418 4th St NW, Albuquerque, NM 87102, USA
user_id 42559731
trip_ledger_id 2340035
Name: 34221, dtype: object
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 17 Engenharia de Dados De 66
➢ Usando at(), com a posição, como fez nos exemplos de fatiamento, e um 
nome de coluna, você pode selecionar um único valor
➢ Por exemplo, isso pode ser feito para saber a duração da viagem na 
segunda linha:
>>> df.at[2,'DURATION']
'0:01:14'
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 18 Engenharia de Dados De 66
➢ Fatiar e usar loc() e at() extrai dados com base na posição, mas você também 
pode usar DataFrames para selecionar linhas com base em alguma condição
➢ Usando o método where, você pode passar uma condição, conforme mostrado 
no seguinte bloco de código:
>>> user=df.where(df['user_id']==8417864)
>>> user
 month trip_id region_id ... user_id trip_ledger_id
0 May 1613335.0 202.0 ... 8417864.0 1488546.0
1 May 1613639.0 202.0 ... 8417864.0 1488838.0
2 May 1613708.0 202.0 ... 8417864.0 1488851.0
... ... ... ... ... ... ...
34221 NaN NaN NaN ... NaN NaN
34222 NaN NaN NaN ... NaN NaN
34223 NaN NaN NaN ... NaN NaN
[34226 rows x 11 columns]
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 19 Engenharia de Dados De 66
➢ O código e os resultados anteriores mostram os resultados de where 
com a condição do ID do usuário sendo igual a 8417864
➢ Os resultados substituem os valores que não atendem aos critérios como 
NaN
➢ Isso será abordado adiante
➢ Pode-se obter os mesmos resultados semelhantes ao exemplo anterior, 
exceto pelo uso de uma notação diferente, e este método não incluirá as 
linhas NaN
➢ Você pode passar a condição para o DataFrame como fez com os nomes 
das colunas. O exemplo a seguir mostra como:
df [(df ['user_id'] == 8417864)]
➢ Os resultados do código anterior são iguais aos do exemplo where(), 
mas sem as linhas NaN, portanto, o DataFrame terá apenas quatro linhas
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 20 Engenharia de Dados De 66
➢ Usando ambas as notações, você pode combinar declarações 
condicionais
➢ Usando a mesma condição de ID de usuário, você pode adicionar uma 
condição de ID de viagem. O exemplo a seguir mostra como:
➢>>> one=df['user_id']==8417864
➢>>> two=df['trip_ledger_id']==1488838
➢>>> df.where(one & two)
➢ month trip_id region_id ... user_id trip_ledger_id
➢0 NaN NaN NaN ... NaN NaN
➢1 May 1613639.0 202.0 ... 8417864.0 1488838.0
➢2 NaN NaN NaN ... NaN NaN
➢... ... ... ... ... ... ...
➢34221 NaN NaN NaN ... NaN NaN
➢34222 NaN NaN NaN ... NaN NaN
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 21 Engenharia de Dados De 66
➢ Usando a segunda notação, a saída é a seguinte:
>>> df[(one)&(two)]
 month trip_id region_id ... user_id trip_ledger_id
1 May 1613639 202 ... 8417864 1488838
[1 rows x 11 columns]
➢ Nos exemplos anteriores, as condições foram atribuídas a uma variável e 
combinadas na notação where e secundária, gerando os resultados 
esperados
Limpeza, Transformação e Enriquecimento de Dados
Exploração básica de dados
Pág. 22 Engenharia de Dados De 66
➢ Agora que você viu os dados, pode começar a analisá-los
➢ Usando o método describe, você pode ver uma série de estatísticas 
relativas aos seus dados
➢ Nas estatísticas, há um conjunto de estatísticas conhecido como resumo 
de cinco números, e describe() é uma variante disso:
>>> df.describe()
 trip_id region_id vehicle_id user_id trip_ledger_id
count 3.422600e+04 34226.0 3.422600e+04 3.422600e+04 3.422600e+04
mean 2.004438e+06 202.0 5.589507e+06 3.875420e+07 1.869549e+06
std 2 .300476e+05 0.0 2.627164e+06 4.275441e+06 2.252639e+05
min 1.613335e+06 202.0 1.034847e+06 1.080200e+04 1.488546e+06
25% 1.813521e+06 202.0 3.260435e+06 3.665710e+07 1.683023e+06
50%1.962520e+06 202.0 5.617097e+06 3.880750e+07 1.827796e+06
75% 2.182324e+06 202.0 8.012871e+06 4.222774e+07 2.042524e+06
max 2.482335e+06 202.0 9.984848e+06 4.258732e+07 2.342161e+06
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 23 Engenharia de Dados De 66
➢ O método de descrição (describe) não é muito útil, a menos que você 
tenha dados numéricos
➢ Se você estivesse observando as idades, por exemplo, isso mostraria 
rapidamente a distribuição das idades, e você seria capaz de ver 
rapidamente erros como idades negativas ou muitas idades acima de 
100
➢ O uso de describe() em uma única coluna às vezes é mais útil
➢ Vamos tentar olhar para a coluna start_location_name. O código e os 
resultados são mostrados no seguinte bloco de código:
>>> df['start_location_name'].describe()
count 34220
unique 2972
top 1898 Mountain Rd NW, Albuquerque, NM 87104, USA
freq 1210
Name: start_location_name, dtype: object
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 24 Engenharia de Dados De 66
➢ Os dados não são numéricos, portanto, obtemos um conjunto diferente 
de estatísticas, mas eles fornecem alguns insights
➢ Dos 34220 locais de partida, existem, na verdade, 2972 locais exclusivos
➢ O local superior (1898 Mountain Rd NW) é responsável por 1210 locais 
de início de viagem
➢ Posteriormente, você irá geocodificar esses dados - adicionar 
coordenadas ao endereço - e saber os valores exclusivos significa que 
você só precisa geocodificar aqueles 2.972 e não os 34.220 completos
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 25 Engenharia de Dados De 66
➢ Outro método que permite ver detalhes sobre seus dados é value_counts
➢ O método value_counts fornecerá o valor e a contagem de todos os valores 
exclusivos
➢ Precisamos chamá-lo para uma única coluna, o que é feito no seguinte trecho:
>>> df['DURATION'].value_counts()
0:04:00 825
0:03:00 807
0:05:00 728
0:06:00 649
0:07:00 627
 ... 
0:40:15 1
39:24:42 1
0:43:09 1
1:05:10 1
1:12:07 1
Name: DURATION, Length: 4135, dtype: int64
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 26 Engenharia de Dados De 66
➢ A partir desse método, você pode ver que 0:04:00 está no topo com uma 
frequência de 825 - que você poderia ter descoberto com describe () - mas 
também pode ver a frequência de todos os outros valores
➢ Para ver a frequência como uma porcentagem, você pode passar o parâmetro 
normalize (que é False por padrão):
>>> df['DURATION'].value_counts(normalize=True)
0:04:00 0.025847
0:03:00 0.025284
0:05:00 0.022808
0:06:00 0.020333
 ... 
0:40:15 0.000031
39:24:42 0.000031
0:43:09 0.000031
1:05:10 0.000031
Name: DURATION, Length: 4135, dtype: float64
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 27 Engenharia de Dados De 66
➢ Pode-se notar que nenhum valor representa uma porcentagem significativa da 
duração
➢ Você também pode passar o parâmetro dropna
➢ Por padrão, value_counts() define como True e você não os verá. Definindo 
como False, você pode ver que end_location_name está sem 2070 entradas:
>>> df['end_location_name'].value_counts(dropna=False)
NaN 2070
1898 Mountain Rd NW, Albuquerque, NM 87104, USA 802
Central @ Tingley, Albuquerque, NM 87104, USA 622
330 Tijeras Ave NW, Albuquerque, NM 87102, USA 529
2550 Central Ave NE, Albuquerque, NM 87106, USA 478
 ... 
116 Washington St SE, Albuquerque, NM 87108, USA 1
716 Commercial St SE, Albuquerque, NM 87102, USA 1
119 Walter St SE, Albuquerque, NM 87102, USA 1
3801 Carlisle Blvd NE, Albuquerque, NM 87107, USA 1
Name: end_location_name, Length: 4264, dtype: int64
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 28 Engenharia de Dados De 66
➢ A melhor maneira de descobrir quantos valores ausentes você tem em suas 
colunas é usar o método isnull(). O código a seguir combina isnull() com sum() 
para obter as contagens:
>>> df.isnull().sum()
month 0
trip_id 0
region_id 0
vehicle_id 0
started_at 0
ended_at 0
DURATION 2308
start_location_name 6
end_location_name 2070
user_id 0
trip_ledger_id 0
dtype: int64
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 29 Engenharia de Dados De 66
➢ Outro parâmetro de value_counts() são bins
➢ O dataset da scooter não tem uma boa coluna para isso, mas usando uma 
coluna numérica, você obteria resultados como o seguinte:
>>> df ['trip_id']. value_counts (bins = 10)
(1787135.0, 1874035.0] 5561
(1700235.0, 1787135.0] 4900
(1874035.0, 1960935.0] 4316
(1960935.0, 2047835.0] 3922
(2047835.0, 2134735.0] 3296
(2221635.0, 2308535.0] 2876
(2308535.0, 2395435.0] 2515
(2134735.0, 2221635.0] 2490
(2395435.0, 2482335.0] 2228
(1612465.999, 1700235.0] 2122
Name: trip_id, dtype: int64
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 30 Engenharia de Dados De 66
➢ Esses resultados são bastante insignificantes, mas se for usado em uma 
coluna como idade, seria útil, pois você pode criar grupos de idade 
rapidamente e ter uma ideia da distribuição
➢ Agora que você explorou e analisou os dados, deve ter uma 
compreensão do que são os dados e quais são os problemas - por 
exemplo, nulos, dtypes impróprios, combinados e campos
➢ Com esse conhecimento, você pode começar a limpar os dados
➢ Em seguida será explicado como corrigir problemas comuns de dados
Limpeza, Transformação e Enriquecimento de Dados
Analisando os dados
Pág. 31 Engenharia de Dados De 66
➢ Seus dados podem parecer especiais, são únicos, você criou os melhores 
sistemas do mundo para coletá-los e fez tudo o que podia para garantir 
que fossem limpos e precisos
➢ Parabéns! Mas é quase certo que seus dados tenham alguns problemas, 
e esses problemas não são especiais ou únicos e são provavelmente 
resultado de seus sistemas ou da entrada de dados
➢ O conjunto de dados da e-scooter é coletado usando GPS com pouca ou 
nenhuma entrada humana, mas faltam localizações finais
➢ Como é possível que uma scooter tenha sido alugada, conduzida e 
parada, mas os dados não sabem onde ela parou? 
➢ Parece estranho, mas aqui estamos
➢ Vamos aprender a lidar com problemas comuns de dados usando o 
conjunto de dados e-scooter
Limpeza, Transformação e Enriquecimento de Dados
Lidando com problemas comuns de dados usando o pandas
Pág. 32 Engenharia de Dados De 66
➢ Antes de modificar qualquer campo em seus dados, você deve primeiro 
decidir se vai usar todos os campos
➢ Olhando para os dados da e-scooter, há um campo denominado 
region_id
➢ Este campo é um código usado pelo fornecedor para rotular Albuquerque
➢ Como estamos usando apenas os dados de Albuquerque, não precisamos 
desse campo, pois ele não adiciona nada aos dados
➢ Você pode descartar colunas usando o método de eliminação
➢ O método permitirá que você especifique se deseja descartar uma linha 
ou uma coluna
➢ Linhas são o padrão, portanto, especificaremos colunas, conforme 
mostrado no seguinte bloco de código:
df.drop(columns=['region_id'], inplace=True)
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 33 Engenharia de Dados De 66
➢ Especificando as colunas a serem eliminadas, você também precisa 
adicionar inplace para fazê-lomodificar o DataFrame original
➢ Para eliminar uma linha, você só precisa especificar o índice em vez das 
colunas
➢ Para eliminar a linha com o índice de 34225, você precisa usar o 
seguinte código:
df.drop(index=[34225],inplace=True)
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 34 Engenharia de Dados De 66
➢ O código anterior funciona quando você deseja descartar uma coluna ou linha 
inteira, mas e se você quisesse eliminá-los com base em condições?
➢ A primeira condição que você pode querer considerar é onde há nulos. Se você 
não tiver dados, a coluna e a linha podem não ser úteis, ou podem distorcer os 
dados. Para lidar com isso, você pode usar dropna().
➢ Ao usar dropna(), você pode passar o eixo, como, o limite, o subconjunto e o 
local nos parâmetros:
✔ axis especifica linhas ou colunas com índices ou colunas (0 ou 1). O padrão é 
linhas.
✔ how especifica se deve-se descartar linhas ou colunas se todos os valores 
forem nulos ou se algum valor for nulo (todos ou algum). O padrão é 
qualquer
✔ thresh permite mais controle do que permitir que você especifique um valor 
inteiro de quantos nulos devem estar presentes
✔ subset permite que você especifique uma lista de linhas ou colunas a serem 
pesquisadas
✔ inplace permite que você modifique o DataFrame existente. O padrão é False.
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 35 Engenharia de Dados De 66
➢ Observando os dados da e-scooter, há seis linhas sem nome de local de 
início:
>>> df['start_location_name'][(df['start_location_name'].isnull())]
26042 NaN
26044 NaN
26046 NaN
26048 NaN
26051 NaN
26053 NaN
Name: start_location_name, dtype: object
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 36 Engenharia de Dados De 66
➢ Para eliminar essas linhas, você pode usar dropna em axis = 0 com how 
= any, que são os padrões
➢ Isso, no entanto, excluirá as linhas onde existem outros nulos, como 
end_location_name
➢ Portanto, você precisará especificar o nome da coluna como um 
subconjunto, conforme mostrado no seguinte bloco de código:
df.dropna(subset=['start_location_name'],inplace=True)
➢ Então, ao selecionar nulos no campo start_location_name como no bloco 
de código anterior, você obterá uma série vazia:
>>> df['start_location_name'][(df['start_location_name'].isnull())]
Series([], Name: start_location_name, dtype: object)
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 37 Engenharia de Dados De 66
➢ Eliminar uma coluna inteira com base em valores ausentes só pode fazer 
sentido se uma certa porcentagem de linhas for nula
➢ Por exemplo, se mais de 25% das linhas forem nulas, você pode 
descartá-las
➢ Você pode especificar isso no limite usando algo como o seguinte código 
para o parâmetro de limite:
thresh=int(len(df)*.25)
➢ Antes de mostrar filtros mais avançados para descartar linhas, você 
pode não querer descartar nulos
➢ Você pode querer preenchê-los com um valor. Você pode usar fillna() 
para preencher colunas ou linhas nulas:
df.fillna(value='00:00:00',axis='columns')
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 38 Engenharia de Dados De 66
➢ E se você quiser usar fillna(), mas usar valores diferentes dependendo da coluna?
➢ Você não gostaria de ter que especificar uma coluna toda vez e executar fillna() 
múltiplas vezes 
➢ Pode-se especificar um objeto para mapear para o DataFrame e passá-lo como o 
parâmetro de valor
➢ No código a seguir, copiaremos as linhas em que os locais de início e término são 
nulos. Em seguida, criaremos um objeto de valor que atribui um nome de rua ao 
campo start_location_name e um endereço de rua diferente ao campo 
end_location_name
➢ Usando fillna(), passamos o valor para o parâmetro de valor e, em seguida, 
imprimimos essas duas colunas no DataFrame, mostrando a alteração:
startstop=df[(df['start_location_name'].isnull())&(df['end_location_name'].isnull())]
value={'start_location_name':'Start St.','end_location_name':'Stop St.'}
startstop=startstop.fillna(value=value)
startstop[['start_location_name','end_location_name']]
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 39 Engenharia de Dados De 66
➢ Você pode descartar linhas com base em filtros mais avançados
➢ Por exemplo, se quiser descartar todas as linhas em que o mês é maio?
➢ Pode-se iterar por meio do DF e descartar se for maio
➢ Poderia também filtrar as linhas e passar o índice para o método drop
➢ É possível filtrar o DataFrame e passá-lo para um novo:
>>> may=df[(df['month']=='May')]
>>> may
 month trip_id region_id ... user_id trip_ledger_id
0 May 1613335 202 ... 8417864 1488546
1 May 1613639 202 ... 8417864 1488838
2 May 1613708 202 ... 8417864 1488851
... ... ... ... ... ... ...
4220 May 1737356 202 ... 35714580 1608429
4221 May 1737376 202 ... 37503537 1608261
4222 May 1737386 202 ... 37485128 1608314
[4225 rows x 11 columns]
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 40 Engenharia de Dados De 66
➢ Também pode-se usar o drop() no DataFrame original e passar o índice 
para as linhas no DataFrame de may criado anteriormente, como 
mostrado:
df.drop(index=may.index,inplace=True)
➢ Agora, se você olhar para os meses no DataFrame original, verá que está 
faltando maio:
>>> df['month'].value_counts()
June 20259
July 9742
Name: month, dtype: int64
➢ Agora que você removeu as linhas e colunas desnecessárias ou 
inutilizáveis devido à falta de dados, é hora de formatá-las
Limpeza, Transformação e Enriquecimento de Dados
Eliminando linhas e colunas
Pág. 41 Engenharia de Dados De 66
➢ A primeira coisa que se destacou anteriormente foi que havia uma única coluna, 
duration, que estava toda em maiúsculas
➢ A capitalização é um problema comum
➢ Muitas vezes você encontrará colunas com todas as letras maiúsculas ou com 
letras maiúsculas - onde a primeira letra de cada palavra é maiúscula - e se um 
codificador a escreveu, você pode encontrar letras maiúsculas - onde a primeira 
letra é minúscula e a primeira letra da próxima palavra é maiúscula sem 
espaços, como em camelCase
➢ O código a seguir tornará todas as colunas em letras minúsculas:
>>> df.columns=[x.lower() for x in df.columns]
>>> print(df.columns)
Index(['month', 'trip_id', 'region_id', 'vehicle_id', 'started_at', 'ended_at',
 'duration', 'start_location_name', 'end_location_name', 'user_id',
 'trip_ledger_id'],
 dtype='object')
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 42 Engenharia de Dados De 66
➢ O código anterior é uma versão condensada de um loop for
➢ O que acontece no loop vem antes do loop for
➢ O código anterior diz que, para cada item em df.columns, torne-o em 
minúsculas e atribua-o de volta a df.columns
➢ Você também pode usar capitalize(), que é titlecase, ou upper() 
conforme mostrado:
>>> df.columns=[x.upper() for x in df.columns] 
>>> print(df.columns)
Index(['MONTH', 'TRIP_ID', 'REGION_ID', 'VEHICLE_ID', 'STARTED_AT',
 'ENDED_AT','DURATION', 'START_LOCATION_NAME',
 'END_LOCATION_NAME', 'USER_ID','TRIP_LEDGER_ID'],
 dtype='object')
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 43 Engenharia de Dados De 66
➢ Você notará um parâmetro no local definido como True
➢ Quando usamos psycopg2 para modificar bancos de dados, precisamos usar 
conn.commit() para torná-lo permanente, e você precisa fazer o mesmo com 
DataFrames
➢ Quando se modifica um DataFrame, o resultado é retornado
➢ Você pode armazenar esse novo DataFrame (resultado) em uma variável e o 
DataFrame original permanece inalterado
➢ Se você deseja modificar o DataFrameoriginal e não atribuí-lo a outra variável, 
deve usar o parâmetro inplace
➢ O método de renomeação funciona para corrigir o caso dos nomes das colunas, 
mas não é a melhor escolha
➢ É melhor usado para realmente alterar nomes de colunas múltiplas
➢ Você pode passar um objeto com remapeamento de vários nomes de coluna
➢ Por exemplo, você pode remover o sublinhado em region_id usando renomear
➢ No próximo código alteraremos a coluna DURATION para minúsculas e 
removemos o sublinhado em region_id
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 44 Engenharia de Dados De 66
➢ Neste código alteramos a coluna DURATION para minúsculas e 
removemos o sublinhado em region_id
df.rename(columns={'DURATION':'duration','region_id':'region'},inplace
=True)
➢ É bom conhecer diferentes maneiras de realizar a mesma tarefa e você 
pode decidir qual faz mais sentido para o seu caso de uso
➢ Agora que você aplicou as alterações aos nomes das colunas, também 
pode aplicar essas funções aos valores nas colunas
➢ Em vez de usar df.columns, você especificará qual coluna modificar e, 
em seguida, se deseja torná-la upper(), lower() ou capitalize()
➢ No seguinte snippet de código, tornamos a coluna do mês toda em 
maiúsculas:
df['month']=df['month'].str.upper()
df['month'].head()
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 45 Engenharia de Dados De 66
➢ Pode não importar a capitalização nos nomes das colunas ou nos valores
➢ No entanto, é melhor ser consistente
➢ No caso dos dados da scooter, ter um nome de coluna em maiúsculas, 
enquanto o resto era todo inferior, ficaria confuso
➢ Imagine um cientista de dados consultando dados de vários bancos de 
dados ou de seu data warehouse e tendo que lembrar que todas as suas 
consultas precisavam levar em conta o campo de duração em letras 
maiúsculas e, quando eles se esqueciam, seu código falhava
➢ Você pode adicionar dados ao DataFrame criando colunas usando o 
formato df['nome da nova coluna'] = valor
➢ O formato anterior criaria uma nova coluna e atribuiria o valor a cada 
linha
➢ Você pode iterar por meio de um DataFrame e adicionar um valor com 
base em uma condição, como no exemplo a seguir:
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 46 Engenharia de Dados De 66
➢ Você pode iterar por meio de um DataFrame e adicionar um valor com base em 
uma condição, como no exemplo a seguir:
for i,r in df.head().iterrows():
 if r['trip_id']==1613335:
 df.at[i,'new_column']='Yes'
 else:
 df.at[i,'new_column']='No'
 df[['trip_id','new_column']].head()
➢ A iteração por meio de DataFrames funciona, mas pode ser muito lenta. Para 
realizar a mesma coisa que o exemplo anterior, mas com mais eficiência, você 
pode usar loc() e passar a condição, o nome da coluna e o valor. O exemplo a 
seguir mostra o código e os resultados:
df.loc[df['trip_id']==1613335,'new_column']='1613335'
df[['trip_id','new_column']].head()
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 47 Engenharia de Dados De 66
➢ Outra maneira de criar colunas é dividir os dados e, em seguida, inseri-los no 
DataFrame
➢ Você pode usar str.split() em uma série para dividir o texto em qualquer 
separador, ou um pat(abreviação de pattern) como o parâmetro é chamado
➢ Pode-se especificar quantas divisões deseja que ocorram, -1 e 0 significam 
todas as divisões, mas qualquer número inteiro é permitido
➢ Por exemplo, se você tem 1.000.000 e deseja apenas dois itens, pode dividir (2) 
na vírgula e obter 1 e 000.000
➢ Você também pode expandir as divisões em colunas usando (expand = True).
➢ Se você não definir a expansão como True, obterá uma lista na coluna, que é o 
padrão
➢ Além disso, se você não especificar um separador, serão usados espaços em 
branco. Os padrões são mostrados:
df['started_ad=df[['trip_id','started_at']].head()
df['started_at'].str.split()
df
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 48 Engenharia de Dados De 66
➢ Você pode expandir os dados e passá-los para uma nova variável
➢ Em seguida, você pode atribuir as colunas a uma coluna no DataFrame original
➢ Por exemplo, se você quiser criar uma coluna de data e hora, poderá fazer o 
seguinte:
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
>>> new=df['started_at'].str.split(expand=True)
>>> new
 0 1
4225 6/1/2019 0:00
4226 6/1/2019 0:01
... ... ...
34221 7/21/2019 23:51
34222 7/21/2019 23:52
[30001 rows x 2 columns]
>>> df['date']=new[0]
>>> df['time']=new[1]
>>> df
 month trip_id region_id ... date time
4225 June 1737416 202 ... 6/1/2019 0:00
4226 June 1737432 202 ... 6/1/2019 0:01
 ... ... … ... ... ... ...
34221 July 2482235 202 ... 7/21/2019 23:51
34222 July 2482254 202 ... 7/21/2019 23:52
[30001 rows x 14 columns]
Pág. 49 Engenharia de Dados De 66
➢ A coluna started_at é um objeto e, olhando para ela, deve ficar claro que é um 
objeto datetime
➢ Se você tentar filtrar no campo started_at usando uma data, ele retornará todas 
as linhas, conforme mostrado:
>>> when = '2019-05-23'
>>> x=df[(df['started_at']>when)]
>>> len(x)
34226
➢ O comprimento de todo o DataFrame é 34226, portanto, o filtro retornou todas 
as linhas. Não era isso que queríamos
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 50 Engenharia de Dados De 66
➢ Usando to_datetime(), você pode especificar a coluna e o formato
➢ Você pode atribuir o resultado à mesma coluna ou especificar um novo
➢ No exemplo a seguir, a coluna started_at é substituída pelo novo tipo de dados 
datetime:
df['started_at']=pd.to_datetime(df['started_at'],
 format='%m/%d/%Y %H:%M')
df.dtypes
➢ Agora, a coluna started_at é um tipo de dados datetime e não um objeto
➢ Com isto pode-se executar consultas usando datas, como tentamos anteriormente no 
DataFrame completo e falhou:
when = '2019-05-23'
df[(df['started_at']>when)]
 trip_id started_at
4 1636714 2019-05-24 13:38:00
➢O restante das linhas ocorreu em 21/05/2019, portanto, obtivemos os resultados 
que esperávamos
➢ Agora que você pode adicionar e remover linhas e colunas, substituir nulos e criar 
colunas, vamos aprender como enriquecer seus dados com fontes externas
Limpeza, Transformação e Enriquecimento de Dados
Criação e modificação de colunas
Pág. 51 Engenharia de Dados De 66
➢ Os dados da e-scooter são dados geográficos - contêm localizações - mas 
carecem de coordenadas
➢ Se você deseja mapear ou realizar consultas espaciais nesses dados, você 
precisará de coordenadas
➢ Você pode obter coordenadas geocodificando o local
➢ Por sorte, a cidade de Albuquerque tem um geocodificador público que 
podemos usar
➢ Para este exemplo, vamos pegar um subconjunto dos dados
➢ Usaremos os cinco principais locais de partida mais frequentes
➢ Em seguida, os colocaremos em um DataFrame usando o seguinte código:
new=pd.DataFrame(df['start_location_name'].value_counts().head())
new.reset_index(inplace=True)
new.columns=['address','count']
new
Limpeza, Transformação e Enriquecimento de Dados
Enriquecimento de dados
Pág. 52 Engenharia de Dados De 66
➢ O campo de endereço contém mais informações do que precisamos para 
geocodificar
➢ Precisamos apenas do endereço da rua
➢ Você também notará que o segundo registro é uma interseção - Central 
@ Tingley
➢ O geocodificador vai querer a palavra e entre as ruas
➢ Vamos limpar os dados e colocá-los em sua própria coluna:
n=new['address'].str.split(pat=',',n=1,expand=True)
replaced=n[0].str.replace("@","and")
new['street']=n[0]
new['street']=replaced
new
Limpeza, Transformaçãoe Enriquecimento de Dados
Enriquecimento de dados
Pág. 53 Engenharia de Dados De 66
➢ Agora você pode iterar por meio do DataFrame e geocodificar o campo 
rua
➢ Para esta seção, você usará outro CSV e o unirá ao DataFrame
➢ Você pode enriquecer os dados combinando-os com outras fontes de 
dados
➢ Assim como você pode juntar dados de duas tabelas em um banco de 
dados, você pode fazer o mesmo com um DataFrame do pandas
➢ Você pode baixar o arquivo geocodedstreet.csv do repositório GitHub em 
https://github.com/giovanebarcelos/ED20212/blob/main/datasets/geocodedstreet.csv 
➢ Carregue os dados usando pd.read_csv() e você terá um DataFrame com 
uma coluna de rua, bem como uma coluna para as coordenadas x e y. O 
resultado é mostrado da seguinte forma:
geo=pd.read_csv('geocodedstreet.csv')
geo
Limpeza, Transformação e Enriquecimento de Dados
Enriquecimento de dados
https://github.com/giovanebarcelos/ED20212/blob/main/datasets/geocodedstreet.csv
Pág. 54 Engenharia de Dados De 66
➢ Para enriquecer o DataFrame original com esses novos dados, você pode 
unir ou mesclar os DataFrames
➢ Usando uma junção, você pode começar com um DataFrame e adicionar 
o outro como parâmetro
➢ Você pode passar como juntar usando left, right ou inner, assim como 
faria no SQL
➢ Você pode adicionar um sufixo esquerdo e direito para que as colunas 
que se sobrepõem possam determinar de onde vieram
➢ Unimos os dois DataFrames no seguinte exemplo:
joined=new.join(other=geo,how='left',lsuffix='_new',rsuffix='_geo')
joined[['street_new','street_geo','x','y']]
Limpeza, Transformação e Enriquecimento de Dados
Enriquecimento de dados
Pág. 55 Engenharia de Dados De 66
➢ A coluna da rua está duplicada e possui um sufixo à esquerda e à direita
➢ Isso funciona, mas é desnecessário, e acabaríamos descartando uma 
coluna e renomeando a coluna restante, o que é apenas um trabalho 
extra
➢ Você pode usar mesclar para unir os DataFrames em uma coluna e não 
ter duplicatas
➢ Merge permite que você passe os DataFrames para mesclar, bem como o 
campo para juntar, como mostrado:
>>> merged=pd.merge(new,geo,on='street')
>>> merged.columns
Index(['address', 'count', 'street', 'x', 'y'], dtype='object')
Limpeza, Transformação e Enriquecimento de Dados
Enriquecimento de dados
Pág. 56 Engenharia de Dados De 66
➢ Observe como os novos campos x e y do merge vieram para o novo 
DataFrame, mas há apenas uma única coluna de rua
➢ Isso é muito mais limpo
➢ Em ambos os casos, unidos ou mesclados, você só pode usar o índice se 
ele estiver definido em ambos os DataFrames
➢ Agora que você sabe como limpar, transformar e enriquecer os dados, é 
hora de reunir essas habilidades e construir um pipeline de dados 
usando esse novo conhecimento
➢ Em seguida usaremos o Airflow e o NiFi para construir um pipeline de 
dados
Limpeza, Transformação e Enriquecimento de Dados
Enriquecimento de dados
Pág. 57 Engenharia de Dados De 66
➢ Agora que você pode limpar seus dados em Python, pode criar funções 
para realizar diferentes tarefas
➢ Ao combinar as funções, você pode criar um pipeline de dados no Airflow
➢ O exemplo a seguir limpará os dados e, em seguida, os filtrará e gravará 
no disco
➢ Começando com o mesmo código do Airflow que você usou nos exemplos 
anteriores, configure as importações e os argumentos padrão, conforme 
mostrado:
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow
Pág. 58 Engenharia de Dados De 66
import datetime as dt
from datetime import timedelta
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from airflow.operators.python_operator import PythonOperator
import pandas as pd
default_args = {
 'owner': 'penelopecharmosa',
 'start_date': dt.datetime(2021, 8, 13),
 'retries': 1,
 'retry_delay': dt.timedelta(minutes=5),
}
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow – Código Python
Pág. 59 Engenharia de Dados De 66
➢ Agora você pode escrever as funções que realizarão as tarefas de 
limpeza
➢ Primeiro, você precisa ler o arquivo, depois pode eliminar o ID da região, 
converter as colunas em minúsculas e alterar o campo started_at para 
um tipo de dados datetime
➢ Por último, grave as alterações em um arquivo. A seguir está o código:
def cleanScooter():
 df=pd.read_csv('scooter.csv')
 df.drop(columns=['region_id'], inplace=True)
 df.columns=[x.lower() for x in df.columns]
 df['started_at']=pd.to_datetime(df['started_at'],
 format='%m/%d/%Y %H:%M')
 df.to_csv('cleanscooter.csv')
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow
Pág. 60 Engenharia de Dados De 66
➢ Em seguida, o pipeline lerá os dados limpos e filtrará com base em uma 
data de início e término. O código é o seguinte:
def filterData():
 df=pd.read_csv('cleanscooter.csv')
 fromd = '2019-05-23'
 tod='2019-06-03'
 tofrom = df[(df['started_at']>fromd)&(df['started_at']<tod)]
 tofrom.to_csv('may23-june3.csv')
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow
Pág. 61 Engenharia de Dados De 66
➢ Essas duas funções devem parecer familiares, pois o código é linha por 
linha igual aos exemplos anteriores, apenas reagrupado
➢ Em seguida, você precisa definir os operadores e tarefas
➢ Você usará PythonOperator e apontará para suas funções
➢ Crie o DAG e as tarefas conforme mostrado:
with DAG('CleanData',
 default_args=default_args,
 schedule_interval=timedelta(minutes=5), # '0 * * * *',
 ) as dag:
 cleanData = PythonOperator(task_id='clean',
 python_callable=cleanScooter)
 selectData = PythonOperator(task_id='filter',
 python_callable=filterData)
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow
Pág. 62 Engenharia de Dados De 66
➢ Neste exemplo, adicionaremos outra tarefa usando o BashOperator 
novamente
➢ Anteriormente apenas para imprimimos uma mensagem no terminal
➢ Desta vez, você o usará para mover o arquivo da tarefa selectData e 
copiá-lo para a área de trabalho. O código é o seguinte:
moveFile = BashOperator(
 task_id='move',
 bash_command='mv may23-june3.csv /path/.')
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow
Pág. 63 Engenharia de Dados De 66
➢ O comando anterior apenas usa o comando de cópia do Linux para fazer 
uma cópia do arquivo
➢ Ao trabalhar com arquivos, você precisa ter cuidado para que suas 
tarefas possam acessá-los
➢ Se vários processos tentarem tocar no mesmo arquivo ou um usuário 
tentar acessá-lo, você poderá interromper o pipeline
➢ Por último, especifique a ordem das tarefas - crie a direção do DAG 
conforme mostrado:
cleanData >> selectData >> copyFile
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow
Pág. 64 Engenharia de Dados De 66
➢ Agora inicialize o webserver e scheduler do airflow 
➢ Agora você pode navegar até http://localhost:8080/ admin para 
visualizar a GUI. Selecione seu novo DAG e poderá ativá-lo e executá-lo. 
Na captura de tela a seguir, você verá o DAG e as execuções de cada 
tarefa:
Limpeza, Transformação e Enriquecimento de Dados
Limpeza de dados usando o Airflow
Pág. 65 Engenharia de Dados De 66
➢ Aprendemos a realizar o EDA básico com o objetivo de localizar erros ou 
problemas em seus dados
➢ Em seguida, você aprendeu como limpar seus dados e corrigir problemas 
comuns de dados
➢ Com esse conjunto de habilidades, você construiu um pipeline de dados 
no Apache Airflow
➢ Em seguida percorreremos um projeto, construindo um pipeline de 
dados 311 e um painel em Kibana
➢ Este projeto utilizará todas as habilidades que você adquiriu até este 
ponto e apresentará uma série de novas habilidades- como construir 
painéis e fazer chamadas de API
Limpeza, Transformação e Enriquecimento de Dados
Resumo
Pág. 66 Engenharia de Dados De 66
Lembre-seLembre-se
“Havia 5 exabytes de informações criados entre o início da 
civilização até 2003, mas essa quantidade de informações 
agora é criada a cada dois dias.”
Eric Schmidt
	Slide 1
	Slide 2
	Slide 3
	Slide 4
	Slide 5
	Slide 6
	Slide 7
	Slide 8
	Slide 9
	Slide 10
	Slide 11
	Slide 12
	Slide 13
	Slide 14
	Slide 15
	Slide 16
	Slide 17
	Slide 18
	Slide 19
	Slide 20
	Slide 21
	Slide 22
	Slide 23
	Slide 24
	Slide 25
	Slide 26
	Slide 27
	Slide 28
	Slide 29
	Slide 30
	Slide 31
	Slide 32
	Slide 33
	Slide 34
	Slide 35
	Slide 36
	Slide 37
	Slide 38
	Slide 39
	Slide 40
	Slide 41
	Slide 42
	Slide 43
	Slide 44
	Slide 45
	Slide 46
	Slide 47
	Slide 48
	Slide 49
	Slide 50
	Slide 51
	Slide 52
	Slide 53
	Slide 54
	Slide 55
	Slide 56
	Slide 57
	Slide 58
	Slide 59
	Slide 60
	Slide 61
	Slide 62
	Slide 63
	Slide 64
	Slide 65
	Slide 66

Continue navegando