Lidar com dados não estruturados é sempre um desafio. Esse tipo de dado pode ter os mais variados formatos e as fontes de dados rudimentares.
Dados não estruturados são em resumo, aqueles que não possuem uma padronização de formatação e não são facilmente categorizados, como por exemplo uma página web de um site. Você provavelmente não controla esse site e extrair dados dele pode ser um desafio. Outro exemplo são dados do poder público que não necessariamente tem o compromisso de serem acessíveis.
A agenda de blocos do carnaval de São Paulo
Anualmente a prefeitura de São Paulo divulga uma agenda com os blocos de carnaval com data, horário, nome e itinerário, entre outras informações.
Nesta série de artigos, quero trazer os seguintes recursos:
- Extrair dados de um PDF e transformá-los em tabulares
- Limpeza básica de dados
- Transformar alguns dados brutos em entidades que depois podem ser usadas de várias maneiras
Primeiro, vamos baixar o pdf de 2024 neste endereço.
O documento possui 35 páginas com uma tabela assim:
O primeiro passo será nós transformarmos esse pdf em uma DataFrame.
import camelot.io as camelot
file_path = "blocos.pdf"
table = camelot.read_pdf(file_path, pages='all')
print(table[0].df)
No código acima estamos fazendo 3 coisas:
- Uso da biblioteca chamada
camelot
, ela irá fazer o trabalho pesado para nós. - Lendo o arquivo com todas as páginas
- Mostrando o dataframe
O resultado foi o seguinte:
0 1 2 3 4 5 6 7
0 BLOCO DATA DO \nDESFILE \n2024 SUBPREFEITURA \nDE ORIGEM ITINERÁRIO 2023 Concentração Desfile Dispersão
1 1 50 tons de Pinga 17/02/2024 - \nPós Carnaval Mooca R. Airi, R. Platina, R. Serra do Japi, R. Serr... 12:00:00 13:00:00 17:00:00
2 2 A Bruxa ta Solta 03/02/2024 - \nPré carnaval Vila Maria/Vila \nGuilherme R. Quedas 500 a 200 14:00:00 15:00:00 19:00:00
3 3 A Ema Gemeu de \nCanto a Canto 17/02/2024 - \nPós Carnaval Freguesia Av. Brigadeiro Faria Lima 364, R. Padre Garcia... 12:00:00 13:00:00 17:00:00
4 4 A Madonna Tá Aqui 03/02/2024 - \nPré carnaval Sé Pateo do Colégio, R. Boa Vista, R. Libero Bada... 11:00:00 12:00:00 16:00:00
5 5 A praça é nossa 03/02/2024 - \nPré carnaval Jabaquara R. Alba, R. das Cavas, Av. João Barreto de Men... 14:00:00 15:00:00 19:00:00
6 6 Abacaxi de Irará 17/02/2024 - \nPós Carnaval Lapa R. Minerva 188, R. Itapicuru, R. Ministro Godó... 10:00:00 11:00:00 15:00:00
7 7 Acadêmicos da \nUrsal 03/02/2024 - \nPré carnaval Sé R. Fortunato, 64, R. Canuto do Val, R. Martim... 11:00:00 12:00:00 16:00:00
8 8 Acadêmicos do \nBaixo Augusta 04/02/2024 - \nPré Carnaval Sé R. Consolação 14:00:00 15:00:00 19:00:00
9 9 Acadêmicos do \nIpanema 03/02/2024 - \nPré carnaval Itaquera R. Filippo Juvara, 296, R. Gondarem, R. Jose S... 14:00:00 15:00:00 19:00:00
Observe que ainda temos espaço para fazer algumas melhorias como retirar \n
que pode atrapalhar a formatação futuramente e o itinerário.
Para retirar as quebra de linha que vieram do pdf, vamos fazer o seguinte:
dataFrame.replace('\n', '', regex=True)
O próximo passo é remover os espaços das colunas
# remove os espaços no nome das colunas
new_header = list(map(lambda x: x.strip(), results_raw.iloc[0]))
results_raw.columns = new_header
# Vamos atribuir a coluna que estava com nome de espaço em branco para bloco
results_raw['BLOCO'] = results_raw['']
results_raw.drop([''], axis='columns', inplace=True)
results_raw.drop([0],inplace=True)
results_raw = results_raw.iloc[1:]
E por fim, vamos extrair a data para uma nova coluna
# extract date
def extract_date(value):
match = re.search(r'\d{2}\/\d{2}\/\d{4}', value)
date = datetime.strptime(match.group(), '%d/%m/%Y').date()
return date
results_raw['data_desfile'] = results_raw['data_do_desfile_2024'].apply(extract_date)
Desse modo já temos os dados limpos e podemos exportar para CSV, ficando mais fácil de disponibilizar:
results_raw.to_csv('carnaval_sp_2024.csv', index=False)
Na próxima parte desta série, vamos trabalhar melhor esses dados fazendo algumas transformações como: datas em ISO 8601, construir itinerário dos blocos e outras coisas.
Top comments (1)
Muito útil! Valeu por compartilhar.