Pandas, Анализ данных

Folium и geopandas для помощи аналитику геоданных.

Время прочтения: 3 мин.

Довольно часто в работе аудитора возникает необходимость анализировать геоданные различного рода (местоположение объектов, маршруты поездок и т.д ). Для наиболее наглядной работы с такими данными хотелось бы осветить возможности таких библиотек, как geopandas и folium.

Для начала необходимо установить все необходимые библиотеки, для этого запустим команду: pip install folium geopandas. Стоит отметить, что установка модуля geopandas на компьютеры с операционной системой Windows может быть сопряжена с рядом проблем. К счастью, в решении данной проблемы нам поможет «всезнающий» Stackoverflow, стоит только изучить этот вопрос по следующей ссылке.

После установки необходимых библиотек, импортируем их внутри нашего проекта:

import folium
import geopandas as gpd
import pandas as pd

Для дальнейшей работы необходимо определиться с тестовой задачей. В рамках обучения работе с данными библиотеками, будем выводить статистику жалоб жителей Москвы по районам.

Для этого нам необходимо загрузить файл в формате geojson с данными по Москве. Данный формат предназначен для хранения различных географических структур в формате JSON.

Откроем наш файл с помощью модуля geopandas:

df = gpd.read_file("mo.geojson")

Объект карты будет храниться как объект класса GeoMap. Класс Geomap на данный момент должен выглядеть следующим образом:

class GeoMap:
    """Конструктор, создает объект карты
    input:координаты центра карты (значения долготы и широты)    
    """
    def __init__(self, x_centre, y_centre):
        self.geo_map = folium.Map(location=[x_centre,y_centre], zoom_start=9, tiles=None)
        folium.TileLayer('CartoDB positron', name="Light Map", control=False).add_to(self.geo_map)

Внутри конструктора создаётся объект карты folium.Map, где указываются следующие аргументы:

location – координаты центра карты;

zoom_start – стартовое значение зума (приближения) на карте;

tiles – использование тайлов карты;

Далее, к созданному объекту добавляем объект тайла TileLayer («подложки») нашей карты.

Теперь добавим возможность разграничения районов на нашей карте с помощью метода create_coropleth.

"""Размечает карту на задаваемые области
input:for_geo_data - geojson файл (или geopandas frame)
for_data - итоговый датафрейм
for columns - колонки, которые будут задействованы в работе
for_key_on - по какой колонке будет происходить построение.
for_legend - легенда карты"""
def create_coropleth(self,for_geo_data,for_data,for_columns,
for_key_on,for_legend):
folium.Choropleth(geo_data=for_geo_data,name='choropleth',
                        data=for_data,columns=for_columns,
                        key_on=for_key_on,fill_color='YlGnBu',
                        fill_opacity=0.9,line_opacity=0.2,
                        legend_name=for_legend
                        ).add_to(self.geo_map)

Создадим объект класса и вызовем реализованный метод:

map_obj = GeoMap(55.75,37.61)
map_obj.create_coropleth(districts_statistic,
districts_statistic,['NAME','COUNT'],'feature.properties.NAME',
'Количество обращений по округам')
map_obj.geo_map

Полученный результат:

Теперь, когда перед глазами карта, появляется желание добавить больше интерактивности и возможностей. Так приступим. Реализуем возможность просмотра статистики по количеству обращений при наведении на конкретный район на карте.


"""Добавляет информацию на карту
input:  df - датафрейм с данными
info_columns - список колонок для отображения информации
labels - список подписей к информации из колонок """
def add_info_on_map(self,df, info_columns,labels):
        style_function = lambda x: {'fillColor':'#ffffff', 'color':'#000000', 'fillOpacity':0.1, 'weight':0.1}
        css=("background-color: white; color: #333333; font-family: arial; font-size: 12px; padding: 10px;") 
        folium_tooltip = folium.features.GeoJsonTooltip(fields = info_columns, aliases = labels, style = css)
        SuburbInfo = folium.features.GeoJson( df, style_function=style_function, control=False,tooltip = folium_tooltip)
        self.geo_map.add_child(SuburbInfo)
        self.geo_map.keep_in_front(SuburbInfo)
        folium.LayerControl().add_to(self.geo_map)

Запустим новый метод и посмотрим на полученный результат:

map_obj.add_info_on_map(districts_statistic,['NAME','COUNT'],
['Название округа','Количество обращений'])
map_obj.geo_map

Теперь при наведении курсора на интересующий район будет выводиться подробная информация о количестве нарушений. С помощью реализованного метода можно добавлять на карту информацию различного рода (количество нарушений, имена управляющих, списки компаний на территории и т.д), т.е ограничений для предоставления статистики нет.

В результате изучения данных библиотек были выявлены и реализованы такие возможности, как:

— формирование интерактивной карты интересующей территории;

— открытие и работа с файлами в формате geojson;

— раграничение интересующей территории на объекты для дальнейшего взаимодействия;

— добавление статистики на объекты карты. Код программы так же размещен на GitHub

Советуем почитать