Vamos construir um painel dos blocos de carnaval de São Paulo usando python? - Parte I

muriloazevedo

Murilo Azevedo

Posted on February 1, 2024

Vamos construir um painel dos blocos de carnaval de São Paulo usando python? - Parte I

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:

Tabela com os dados de cada bloco

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
# 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:]
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
muriloazevedo
Murilo Azevedo

Posted on February 1, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related