Uma representação visual das eleições em São Petersburgo - a mágica do envolvimento de voz

Oi

Em setembro deste ano (2019), foi realizada a eleição do governador de São Petersburgo. Todos os dados de votação estão disponíveis publicamente no site da comissão eleitoral, não quebraremos nada, mas apenas visualizamos as informações deste site www.st-petersburg.vybory.izbirkom.ru da forma que precisamos, faremos uma análise muito simples e identificaremos algumas Padrões "mágicos".

Normalmente, para essas tarefas, eu uso o Google Colab. Este é um serviço que permite a execução de Jupyter Notebooks e, ao ter acesso gratuito à GPU (NVidia Tesla K80), agiliza significativamente a análise de dados e o processamento adicional. Eu precisava de algum trabalho preparatório antes de importar.

%%time !apt update !apt upgrade !apt install gdal-bin python-gdal python3-gdal # Install rtree - Geopandas requirment !apt install python3-rtree # Install Geopandas !pip install git+git://github.com/geopandas/geopandas.git # Install descartes - Geopandas requirment !pip install descartes 

Outras importações.

 import requests from bs4 import BeautifulSoup import numpy as np import pandas as pd import matplotlib.pyplot as plt import geopandas as gpd import xlrd 

Descrição das bibliotecas usadas


  • pedidos - módulo para um pedido para se conectar a um site

  • BeautifulSoup - módulo para analisar documentos html e xml; permite acessar diretamente o conteúdo de qualquer tag em html

  • numpy - um módulo matemático com um conjunto básico e necessário de funções matemáticas

  • pandas - biblioteca de análise de dados

  • matplotlib.pyplot - conjunto de módulos de métodos de construção

  • geopandas - módulo para construção de um mapa eleitoral

  • xlrd - módulo para leitura de arquivos de tabela

Chegou a hora de coletar os dados em si, parsim. O comitê eleitoral cuidou do nosso tempo e forneceu relatórios nas tabelas, é conveniente.

 ### Parser list_of_TIKS = [] for i in range (1, 31): list_of_TIKS.append('   №' + str(i)) num_of_voters = [] num_of_voters_voted = [] appearence = [] votes_for_Amosov_percent = [] votes_for_Beglov_percent = [] votes_for_Tikhonova_percent = [] url = "http://www.st-petersburg.vybory.izbirkom.ru/region/region/st-petersburg?action=show&root=1&tvd=27820001217417&vrn=27820001217413&region=78&global=&sub_region=78&prver=0&pronetvd=null&vibid=27820001217417&type=222" response = requests.get(url) page = BeautifulSoup(response.content, "lxml") main_links = page.find_all('a') for TIK in list_of_TIKS: for main_tag in main_links: main_link = main_tag.get('href') if TIK in main_tag: current_TIK = pd.read_html(main_link, encoding='cp1251', header=0)[7] num_of_voters.extend(int(current_TIK.iloc[0,i]) for i in range (len(current_TIK.columns))) num_of_voters_voted.extend(int(current_TIK.iloc[2,i]) + int(current_TIK.iloc[3,i]) for i in range (len(current_TIK.columns))) appearence.extend(round((int(current_TIK.iloc[2,i]) + int(current_TIK.iloc[3,i]))/int(current_TIK.iloc[0,i])*100, 2) for i in range (len(current_TIK.columns))) votes_for_Amosov_percent.extend(round(float(current_TIK.iloc[12,i][-6]+current_TIK.iloc[12,i][-5]+current_TIK.iloc[12,i][-4]+current_TIK.iloc[12,i][-3]+current_TIK.iloc[12,i][-2]),2) for i in range (len(current_TIK.columns))) votes_for_Beglov_percent.extend(round(float(current_TIK.iloc[13,i][-6]+current_TIK.iloc[13,i][-5]+current_TIK.iloc[13,i][-4]+current_TIK.iloc[13,i][-3]+current_TIK.iloc[13,i][-2]),2) for i in range (len(current_TIK.columns))) votes_for_Tikhonova_percent.extend(round(float(current_TIK.iloc[14,i][-6]+current_TIK.iloc[14,i][-5]+current_TIK.iloc[14,i][-4]+current_TIK.iloc[14,i][-3]+current_TIK.iloc[14,i][-2]),2) for i in range (len(current_TIK.columns))) 

Então, isso é o que foi discutido. Os dados no Google Colab são coletados de maneira inteligente, mas não tanto.

Antes de criar vários gráficos e mapas, é bom ter uma idéia do que chamamos de "conjunto de dados".

Análise dos dados da comissão eleitoral


Na cidade de São Petersburgo, existem 30 comissões territoriais; na 31ª coluna, nos referimos às assembleias de voto digitais.

imagem

Cada comissão territorial possui várias dezenas de PECs (comissões eleitorais anteriores).

imagem

O principal que nos interessa é a aparência em cada assembleia de voto e que tipo de dependências podemos observar. Vou desenvolver o seguinte:

  • dependência de comparecimento e número de assembleias de voto;

  • dependência da porcentagem de votos dos candidatos na participação;

  • Dependência da participação no número de eleitores na delegacia.

A partir da tabela de dados simples, é bastante difícil rastrear como foram as eleições e tirar algumas conclusões, para que os gráficos sejam o nosso caminho.

Vamos construir o que criamos.

 ### Plots Data #Votes in percent (appearence) - no need in extra computations #Appearence (num of voters) - no need in extera computations #Number of UIKs (appearence) interval = 1 interval_num_of_UIKs = [] for i in range (int(100/interval+1/interval)): interval_num_of_UIKs.append(0) for i in range (0, int(100/interval+1/interval), interval): for j in range (len(appearence)): if appearence[j] < (i + interval/2) and appearence[j] >= (i - interval/2): interval_num_of_UIKs[i] = interval_num_of_UIKs[i] + 1 

 ### Plotting #Number of UIKs (appearence) plt.figure(figsize=(10, 6)) plt.plot(interval_num_of_UIKs) plt.axis([0, 100, 0, 200]) plt.ylabel('Number of UIKs in a 1% range') plt.xlabel('Appearence') plt.show() #Votes in percent (appearence) plt.figure(figsize=(10, 10)) plt.scatter(appearence, votes_for_Amosov_percent, c = 'g', s = 6) plt.scatter(appearence, votes_for_Beglov_percent, c = 'b', s = 6) plt.scatter(appearence, votes_for_Tikhonova_percent, c = 'r', s = 6) plt.ylabel('Votes in % for each candidate') plt.xlabel('Appearence') plt.show() #Appearence (num of voters) plt.figure(figsize=(10, 6)) plt.scatter(num_of_voters, appearence, c = 'y', s = 6) plt.ylabel('Appearence') plt.xlabel('Number of voters registereg in UIK') plt.show() 

Dependência da participação e número de assembleias de voto

imagem

Dependência da porcentagem de votos dos candidatos na participação

  • "Verde" - votos para Amosov

  • "Azul" - para Beglov

  • "Vermelho" - para Tikhonov

imagem

Dependência da participação no número de eleitores na delegacia

imagem

As construções são bastante toleráveis, mas no decorrer do trabalho, verificou-se que, em média, 400 pessoas no local e a porcentagem de Beglov é de 50 a 70, mas existem dois locais com uma afluência> 1200 pessoas e uma porcentagem de 90 + -0,2. É interessante que isso tenha acontecido nessas áreas. Alguns agitadores fantásticos funcionaram? Ou apenas dirigiu 10 ônibus e foi forçado a votar? De uma forma ou de outra, estamos empolgados, uma pequena investigação está sendo obtida. Mas ainda temos que comprar cartas. Vamos continuar.

Representação visual e trabalho com geopandas


 ### Extra data for visualization: appearence and number of voters by municipal districts current_UIK = pd.read_html(url, encoding='cp1251', header=0)[7] num_of_voters_dist = [] num_of_voters_voted_dist = [] appearence_dist = [] for j in [num_of_voters_dist, num_of_voters_voted_dist, appearence_dist]: j.extend(0 for i in range (18)) districts = { '0' : [1], # '1' : [2], # '2' : [18], # '3' : [16, 30], # '4' : [10, 14, 22], # '5' : [11, 17], # '6' : [4, 25], # '7' : [5, 24], # '8' : [23, 29], # '9' : [9, 12, 28], # '10' : [13], # '11' : [15], # '12' : [21], # '13' : [20], # '14' : [19, 27], # '15' : [3, 7], # '16' : [6, 26], # '17' : [8] # } for i in districts.keys(): for k in range (1, 31): if k in districts[i]: num_of_voters_dist[int(i)]= num_of_voters_dist[int(i)] + int(current_UIK.iloc[0,k-1]) num_of_voters_voted_dist[int(i)] = num_of_voters_voted_dist[int(i)] + int(current_UIK.iloc[2,k-1]) + int(current_UIK.iloc[3,k-1]) for i in range (18): appearence_dist[i] = round(num_of_voters_voted_dist[i]/num_of_voters_dist[i]*100, 2) 

 ### GeoDataFrame SPb_shapes= gpd.read_file('./shapes/Administrative_Discrits.shp', encoding='cp1251') temp = pd.DataFrame({' ': num_of_voters_dist, '':appearence_dist }) temp[''] = SPb_shapes[['']] temp['geometry'] = SPb_shapes[['geometry']] SPB_elections_visualization = gpd.GeoDataFrame(temp) 

 ### Colored districts SPB_elections_visualization.plot(column = '', linewidth=0, cmap='plasma', legend=True, figsize=[15,15]) 



Eles pintaram os distritos administrativos da cidade e os assinaram, parece familiar, parece com Peter, mas o Neva ainda não é suficiente.

Número de eleitores

 ### Number of voters gradient SPB_elections_visualization.plot(column = ' ', linewidth=0, cmap='plasma', legend=True, figsize=[15,15]) 



Participação

 ### Appearence gradient SPB_elections_visualization.plot(column = '', linewidth=0, cmap='plasma', legend=True, figsize=[15,15]) 



Conclusão


Você pode se divertir com os dados por um longo tempo, usá-los em diferentes campos e, é claro, obter algum benefício, pois eles existem. Ferramentas de visualização de geolocalização simples e sofisticadas podem fazer grandes coisas. Escreva sobre o seu sucesso nos comentários!

Source: https://habr.com/ru/post/pt475258/


All Articles