Una representación visual de las elecciones en San Petersburgo: la magia del ajuste de voz

Hola

En septiembre de este año (2019), se celebró la elección del Gobernador de San Petersburgo. Todos los datos de votación están disponibles públicamente en el sitio web de la comisión electoral, no romperemos nada, simplemente visualicemos la información de este sitio web www.st-petersburg.vybory.izbirkom.ru en la forma que necesitemos, realizaremos un análisis muy simple e identificaremos algunos Patrones "mágicos".

Por lo general, para tales tareas, uso Google Colab. Este es un servicio que le permite ejecutar Jupyter Notebooks y, al tener acceso gratuito a la GPU (NVidia Tesla K80), acelerará significativamente el análisis de datos y el procesamiento posterior. Necesitaba un trabajo preparatorio 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 

Más importaciones.

 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 

Descripción de bibliotecas usadas


  • solicitudes: módulo para una solicitud de conexión a un sitio

  • BeautifulSoup - módulo para analizar documentos html y xml; le permite acceder directamente al contenido de cualquier etiqueta en html

  • numpy - un módulo matemático con un conjunto básico y necesario de funciones matemáticas

  • pandas - biblioteca de análisis de datos

  • matplotlib.pyplot: conjunto de módulos de métodos de construcción

  • geopandas - módulo para construir un mapa electoral

  • xlrd - módulo para leer archivos de tabla

Ha llegado el momento de recopilar los datos en sí, parsim. El comité electoral se encargó de nuestro tiempo y proporcionó informes en las tablas, es 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))) 

Entonces, esto es lo que se discutió. Los datos en Google Colab se recopilan de manera inteligente, pero no tanto.

Antes de construir varios gráficos y mapas, es bueno que tengamos una idea de lo que llamamos un "conjunto de datos".

Análisis de los datos de la comisión electoral.


En la ciudad de San Petersburgo hay 30 comisiones territoriales; a ellas, en la columna 31, nos referimos a los colegios electorales digitales.

imagen

Cada comisión territorial tiene varias docenas de PEC (comisiones electorales).

imagen

Lo principal que nos interesa es la aparición en cada mesa electoral y qué tipo de dependencias podemos observar. Construiré sobre lo siguiente:

  • dependencia de la participación y el número de mesas electorales;

  • dependencia del porcentaje de votos para los candidatos en la participación;

  • Dependencia de la participación en el número de votantes en el recinto.

Desde la tabla de datos, es bastante difícil rastrear cómo fueron las elecciones y sacar algunas conclusiones, por lo que los gráficos son nuestra salida.

Construyamos lo que se nos ocurrió.

 ### 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() 

Dependencia de participación y número de mesas electorales.

imagen

Dependencia del porcentaje de votos de los candidatos en la participación.

  • "Verde" - votos para Amosov

  • "Azul" - para Beglov

  • "Rojo" - para Tikhonov

imagen

Dependencia de la participación en el número de votantes en el recinto.

imagen

Las construcciones son bastante tolerables, pero en el transcurso del trabajo resultó que en promedio 400 personas en el sitio y el porcentaje de Beglov es de 50 a 70, pero hay dos sitios con una participación> 1200 personas y un porcentaje de 90 + -0.2. Es interesante que esto haya sucedido en estas áreas. ¿Funcionaron algunos agitadores fantásticos? ¿O simplemente condujo autobuses para 10 personas y se vio obligado a votar? De una forma u otra, estamos entusiasmados, se está obteniendo una pequeña investigación de este tipo. Pero todavía tenemos que robar cartas. Vamos a continuar

Representación visual y trabajo con 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]) 



Pintaron los distritos administrativos de la ciudad y los firmaron, parece familiar, se parece a Peter, pero el Neva todavía no es suficiente.

Numero de votantes

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



Participación

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



Conclusión


Puede divertirse con los datos durante mucho tiempo, usarlos en diferentes campos y, por supuesto, obtener algún beneficio, ya que existen. Las herramientas de visualización de geolocalización simples y sofisticadas pueden hacer grandes cosas. ¡Escribe sobre tu éxito en los comentarios!

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


All Articles