Closed ishouldbedany closed 4 years ago
Tenho feito algumas experiências com o Tabula que me parecem dar resultados aceitáveis.
Já vi alguma variabilidade do nome do concelho de dia para dia, por isso a minha sugestão seria criar um dataset que inicialmente teria, para cada dia, uma linha por concelho, e aí agrupar tudo num ID único.
Fazendo Left Join com uma lista de concelhos também percebemos quais estão a falhar, e podemos colocar a informação a NaN, não sabendo se tem algum infetado ou se o número é 0.
Estando isto feito, podemos usar o pivot_table do pandas para transformar a informação em colunas.
A inclusão seria feita num .csv separado, para evitar problemas com o processo atual.
Cortesia da @centraldedados, temos neste repositório, em data/concelhos.csv
, os 308 concelhos de Portugal, acompanhados do identificador único código de distrito + código de concelho.
O scraping é feito a partir dos dados do site dos CTT e a licença permite o uso, portanto parece um bom ponto de partida.
Sobre os shapefiles, vou tomar a liberdade de convocar quem já demonstrou mestria em tais assuntos neste projecto: @joaopalmeiro , por aí? :grin:
Tentei usar o tabula também mas não consegui resultados muito bons, no fim o que ficou mais fácil para mim foi:
1) Command-line: pdftotext -raw -f 3 -l 3 boletim.pdf
e o seguinte código Python (bem hacky, fiz rapidamente e dá para melhorar):
with open("boletim.txt", "r", encoding="iso-8859-1") as f:
data = f.read().encode("iso-8859-1").decode("utf-8")
lines = data.split()[80:]
d = {}
name_state = ''
skip_words = ['CONCELHO', 'NÚMERO', 'DE', 'CASOS']
for l in lines:
if l in skip_words:
continue
try:
count = int(l)
name_state = name_state.strip()
d[name_state] = count
name_state = ''
except ValueError:
name_state += l + ' '
dfpt = pd.DataFrame.from_dict(d.items())
dfpt.columns = ["city", "cases"]
Resultado (depois de fazer merge com geojson):
Eu tirei algumas cidades fora de Portugal continental mas é fácil ajustar o que faltar também. Enfim, espero que ajude, foi o código que ficou mais simples para mim.
Olá! :smile:
Antes de mais, desculpem a demora em responder!
Relativamente à extração dos dados dos Relatórios de Situação, gostava de começar por partilhar alguns pontos derivados do que andei a fazer (até porque coincidem com algumas das questões colocadas), dado que hoje terminei de extrair os dados (disponíveis aqui, divididos por dia, e ainda a necessitarem de uma certa uniformização em termos de nomenclatura dos concelhos, pelo menos), por concelho, de todos os Relatórios disponíveis (algo que comecei há uns bons dias atrás de modo a ter os dados para criar alguns gráficos mais focados no Alentejo).
Em primeiro lugar, penso que o "maior desafio" deve-se à "irregularidade" na formatação (à falta de melhor palavra) dos próprios Relatórios/PDFs, ou seja, nem todos os Relatórios apresentam tabelas que sejam facilmente extraídas de forma automática. Esta "irregularidade" prende-se, de uma forma mais concreta, à existência de "células" com quebras de linha, ao posicionamento vertical e horizontal do conteúdo dentro das "células" e ao desalinhamento das "linhas" entre tabelas, por exemplo. Para além disso, o pós-processamento dos dados (que poderá ser necessário), na minha perspetiva, está bastante dependente da opções escolhidas para extrair as tabelas dos Relatórios.
A título de exemplo, até dia 9 de abril, utilizei o R e o pdftools (apenas porque já conhecia este pacote e sabia utilizá-lo minimamente) para a extração dos dados das tabelas dos Relatórios, sendo que, para além da necessidade de executar alguma lógica de pós-processamento, tive de ir ajustando, por vezes, algumas coisas ao longo dos dias até conseguir ter um data frame pronto a ser guardado em formato CSV. Contudo, "no dia" 9 de abril, não consegui, em complemento ao que já tinha, adaptar a lógica de pós-processamento para, de forma minimamente "automatizada", estruturar as coisas num data frame (os padrões eram algo aleatórios e teria, dentro do que sei e consigo, introduzir praticamente alguns concelhos "manualmente"). Desta forma, explorei outras hipóteses e deparei-me com o tabulizer, um pacote criado "em cima" do pacote, em Java, que "alimenta" o Tabula. Através da função explore_text()
, consegui extrair a tabela do Relatório de 9 de abril e, aplicando alguma lógica de pós-processamento, chegar ao dito data frame. Daí em diante, necessitei apenas de tornar esta função de pós-processamento mais robusta e desde o Relatório de dia 15 de abril que não necessito de alterar o código, apenas de o correr no RStudio. Quanto à linguagem e às bibliotecas, acabei por não explorar o que é que o Python tem para oferecer.
Posto isto, há, na minha opinião, mais 4 desafios:
(Faro)
(distrito), enquanto que o concelho de Calheta
surge, em geral, seguido de (Açores)
. Deste modo, na minha perspetiva, será necessário extrair, também, esta informação entre parênteses, sendo que esta informação, semanticamente, é díspar.Reguengos de Monsaraz
surge como Reguengos de Monsaraz
, Reg. de Monsaraz
e Reguengos Monsaraz
.Porto
, no dia 30 de março (mais informação aqui), por exemplo, também me deparei com o concelho de Penacova
a surgir duas vezes, com números distintos, no dia 2 de abril. Confirmar todos estes dados é, muito provavelmente, "impossível", mas existe a opção de os cruzar com aqueles reportados por outras entidades, como algumas ARSs, por exemplo.Quanto à identificação dos concelhos, penso que uma boa abordagem seria seguir a hierarquia e a nomenclatura presentes na Carta Administrativa Oficial de Portugal (CAOP) da Direção-Geral do Território (podem encontrar a versão atual, a de 2019, aqui). Esta Carta segue a Nomenclatura das Unidades Territoriais para Fins Estatísticos (NUTS) e possui, também, um identificador numérico único para cada concelho chamado DICO (os dois primeiros digitos dizem respeito ao DIstrito, enquanto que os outros dois dizem respeito ao COncelho). Esta informação está disponível no ficheiro Áreas das freguesias, concelhos, distritos e país disponível aqui, nomeadamente na folha _Areas_ConcelhosCAOP2019. Assim, penso que é "apenas" necessário decidir que campos incluir, de modo a garantir a identificação de todos os concelhos e a desambiguação entre estes, e ter alguma lógica para comparar estes dados com aqueles extraídos. Em complemento, também gostaria de sugerir a introdução de um campo para a ARS de cada concelho.
Relativamente aos shapefiles disponibilizados junto da CAOP, pelo que consegui perceber, só se encontram disponíveis ficheiros divididos por freguesia (um ficheiro para cada Área Administrativa aproximadamente) e com o identificador número único por freguesia (o DICOFRE). Contudo, o shapefile/GeoJSON atualmente disponível aqui no repositório possui uma variável chamada _CC2 que coincide com o DICO, salvo erro.
Por fim, penso que estes dados deveriam ser guardados num novo ficheiro, para além de que opção sugerida pelo @ishouldbedany parece-me uma boa ideia quanto à introdução de todos os concelhos.
Desculpem a resposta bastante longa, mas acho que, desta forma, consegui partilhar o que sei sobre este tópico. Espero que esta partilha vos seja útil! Se precisarem de alguma ajuda, não hesitem em pedir! :smile:
Olá a todos!
Fiz um PR com uma primeira solução usando tabula e python.
O PR inclui um csv com os resultados (relatorios desde 24 Março), pelo q também pode ser usado para comparação de outras soluções.
Como já referido pelo @joaopalmeiro, os nomes dos concelhos não estão uniformizados nos relatorios e este script tambem ainda nao corrige isso.
Obrigado pelo vosso contributo :) Acho que pode ser importante extrair também a % de população que esses números representam, pois varia de dia para dia (aquele asterisco com os 78-83% que tem aparecido, por baixo da tabela dos concelhos). Talvez dê para fazer isso com o script que temos de momento para fazer parse do texto do boletim - vou investigar.
Depois da (magnífica) exposição do @joaopalmeiro sobre este assunto, parece-me que a melhor opção é mesmo identificar os concelhos pelo respectivo DICO, que creio até estar no repositório já falado aqui da @centraldedados.
Não fica tão fácil para quem quiser abrir a folha de cálculo e explorar directamente, porque as colunas passam a ser mapeadas por DICO, mas de qualquer das formas seria um ficheiro com 300 colunas, já não seria muito user-friendly e não.
Paralelamente, poderíamos ter um ficheiro anexo (um .yaml
, um .json
, um outro .csv
, qualquer coisa no formato de dicionário) que mapeasse os DICOs ao nome do respectivo concelho - e poderíamos aí incluir as respectivas variações no nome do concelho.
{
1234: ["Reguengos de Monsaraz", "Reg. de Monsaraz", "Reguengos Monsaraz"]
},
O primeiro elemento de cada lista seria sempre o nome comum e oficial, sendo os seguintes as possíveis variações. Se fosse minimanente sustentável curar esta lista (não sei qual a % de concelhos que pode recair nestes casos), até poderíamos usá-la para fazer a uniformização, ao invés de tentarmos criar heurísticas genéricas (que geralmente se revelam frágeis).
Entretanto foi nos enviada a seguinte informação, com os dados que estão a alimentar o dashboard da ERSI:
http://esriportugal.maps.arcgis.com/home/item.html?id=b895ffa41e8e4f2e8bd957abd9a933cf#data
Estamos a aguardar para ver se a ESRI vai fazer a atualização dos dados por concelho nas novas versões do relatório, antes de fundir esta informação. O script que temos vindo a desenvolver é alimentado pelos dados históricos desse link acima.
Gente, podem usar e abusar de uma script que uso para fazer isso, disponível em: https://github.com/jgrocha/covid-pt/blob/master/Relat%C3%B3rios/relatorio.py
A script usa-se da seguinte forma:
wget https://covid19.min-saude.pt/wp-content/uploads/2020/05/69_DGS_boletim_20200510.pdf
./relatorio.py 2020-05-10 https://covid19.min-saude.pt/wp-content/uploads/2020/05/69_DGS_boletim_20200510.pdf 69_DGS_boletim_20200510.sql
Eu estou a gerar um sql para atualizar a minha BD Postgresql todos os dias. Depois exporto para um geopackage, onde têm os dados todos (geográficos e não geográficos).
Têm um csv com os dados por concelho atualizados, num csv, logo na raiz do repositório, em: https://github.com/jgrocha/covid-pt/blob/master/confirmados_concelho.csv
Com o pandas
, por exemplo, uso diretamente o ficheiro do repositório:
pandemia = pandas.read_csv('https://raw.githubusercontent.com/jgrocha/covid-pt/master/confirmados_concelho.csv')
Se precisarem de alguma coisa, é só dizerem. Posso adaptar o meu o workflow para atualizar este respositório.
Os dados da ESRI são copiados à mão (pelo menos assim era feito no início).
Para já vou fechar, dado que estamos a usar os dados da ESRI (que têm vindo a tratar da atualização diariamente), e que nos traz menos variabilidade em relação a um scraper do PDF, que nos ia roubar algum tempo a fazer eventuais correções. Se virmos que queremos usar o PDF como fonte volto a abrir este tema :)
Obrigado a todos pelas contribuições!
Para desenhar a introdução do número de casos confirmados por concelho (e metadados associados) no repositório, mantendo a fiabilidade e o grau de automatização. Algumas questões a ter em conta: