다운로드
작성자: admin 작성일시: 2018-10-21 18:20:20 조회수: 2275 다운로드: 110
카테고리: 기타 태그목록:

지리 정보 데이터 처리

지리정보데이터, GIS(Geospatial Information System) 라고 말하는 것은 위치에 대한 정보를 광범위하게 포함하는 말이다. 예로는 좌표, 주소, 도시 , 우편번호 등이 있다. 이 절에서는 지리정보를 처리하는데 유용한 패키지와 지리 정보 데이터를 처리하는 방법에 대해 설명할 것이다.

GeoPandas

GeoPandas는 파이썬에서 지리정보 데이터 처리의 기하하적 연산과 시각화 등을 돕는 패키지이다.

설치

  • conda install -c conda-forge geopandas

이름으로도 알 수 있듯이, GeoPandas는 Pandas와 비슷하다. 두 가지의 자료형 GeoSeriesGeoDataFrame이 있다. 다루는 방법에 큰 차이가 없다. 다만 지리정보 데이터 분석에 유용한 속성과 메서드가 존재한다. 다음처럼 gpd라는 이름으로 임포트 하는 것이 관례이다.

In [1]:
import geopandas as gpd
gpd.__version__
Out:
'0.4.0'

GeoPandas는 간단한 지리정보데이터를 실습 할 수 있는 샘플 데이터 셋을 제공한다. 이 데이터를 사용해 GeoPandas의 기초적인 기능을 학습하겠다. 이 실습 데이터는 gpd.dataset.get_path() 명령으로 데이터의 링크를 불러와 사용 한다.

In [2]:
countries = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities'))
In [3]:
countries.tail(3)
Out:
pop_est continent name iso_a3 gdp_md_est geometry
174 49052489.0 Africa South Africa ZAF 491000.0 POLYGON ((31.52100141777888 -29.25738697684626...
175 11862740.0 Africa Zambia ZMB 17500.0 POLYGON ((32.75937544122132 -9.23059905358906,...
176 12619600.0 Africa Zimbabwe ZWE 9323.0 POLYGON ((31.19140913262129 -22.2515096981724,...
In [4]:
cities.tail()
Out:
name geometry
197 Cairo POINT (31.24802236112612 30.05190620510371)
198 Tokyo POINT (139.7494615705447 35.68696276437117)
199 Paris POINT (2.33138946713035 48.86863878981461)
200 Santiago POINT (-70.66898671317483 -33.4480679569341)
201 Singapore POINT (103.853874819099 1.294979325105942)

지리 정보의 시각화

GeoSeries와 GeoDataFrame 객체의 plot()명령을 사용하면, GeoPandas 내부의 Geometry 데이터를 손쉽게 시각화 할 수 있다. 이 때, Geometry 데이터는 지리정보를 표현하는 다각형, 선, 점을 의미하는데, GeoPandas는 내부적으로 다각형, 선, 점을 Shapely 패키지를 사용하여 처리한다. 각 Polygon, LineString, Point 로 정의되어 있다. GeoPandas가 제공하는 데이터에는 Geometry 데이터가 이미 포함되어 있지만, 우리가 가진 데이터를 활용해 생성할 수도 있다. 이 부분은 다음 부분에서 학습 하겠다.

대부분의 경우 지리정보를 시각화 할 때는 위치에 따른 정보의 변화를 함께 표현한다. 이 때는 plot() 명령의 column 인자에 반영하고 싶은 데이터의 열 이름을 입력하면 해당 열의 데이터를 색(color)으로 표현한다. 표현하려는 정보가 카테고리 데이터 일때는 categorical인자를 True로 설정한다.

In [5]:
ax = countries.plot(column="continent", legend=True, categorical=True)
ax.set_title("세계 지도")
ax.set_axis_off()
plt.show()

만약, 표현하고 싶은 컬럼이 실수 변수라면, 색을 변화시키는 기준 즉 데이터를 구분하는 방법과 갯수를 정의할 수 있다. 먼저 구분하는 방법은 plot()명령의 scheme 인자로 설정하는데, 지원하는 것으로는 "Equal_interval"(동일한 간격으로 구분), "Quantiles"(4분위수를 구하여 구분), "Fisher_Jenks"(클래스 내 분산을 줄이고, 클래스 끼리의 분산을 최대화하는 방식으로 구분)가 있다. 구분하는 갯수는 k 인자에 원하는 숫자를 입력하면된다. 디폴트는 5이다.

다음 코드는 국가별 GDP 추정치를 해당 국가의 추정인구로 나누어, 추정 1인당 GDP를 만들고, 이를 지도에서 색으로 표현한 예이다.

추가적으로, 정보를 색으로 나타낼 때는 표현하려는 정보에 따라, 컬러맵을 설정하는 것이 좋다. 이 예와 같이 수치적인 정보를 시각화 할 때는, 수치만큼 색이 밝고 어두워지는 것으로 표현하는 것이 더 적절하기 때문에 Sequence 계열의 컬러맵을 설정하는 것이 좋다. 컬러맵에 대해서는 이 곳을 참고하길 바란다.(https://matplotlib.org/users/colormaps.html)

In [6]:
# 1인당 GDP 연산
countries['gdp_per_cap'] = countries['gdp_md_est'] / countries['pop_est'] * 100

ax = countries.plot(column='gdp_per_cap', legend=True, scheme='quantiles', cmap="Blues", k=5)
ax.set_axis_off()
ax.set_title("세계 국가의 1인당 GDP")
plt.show()
/home/dockeruser/anaconda3/lib/python3.6/site-packages/pysal/__init__.py:65: VisibleDeprecationWarning: PySAL's API will be changed on 2018-12-31. The last release made with this API is version 1.14.4. A preview of the next API version is provided in the `pysal` 2.0 prelease candidate. The API changes and a guide on how to change imports is provided at https://migrating.pysal.org
  ), VisibleDeprecationWarning)

Geometry 데이터

이전에 언급 했듯이, GeoPandas에서는 Shapely라는 패키지를 통해 Geometry 데이터를 처리한다. 여기서는 Geometry 데이터에 대해서 공부해보도록 하자.

Polygons

한 국가의 영토 따위 등은 여러 개의 점을 이은 다각형으로 나타낼 수 있다. "Countries" 데이터에서는 다음처럼 Polygon 데이터를 제공한다.

In [7]:
countries.geom_type[:3]
Out:
0         Polygon
1    MultiPolygon
2         Polygon
dtype: object
In [8]:
# 여러 개의 점(Point)들로 이루어져있다.
print(countries.geometry[113])
POLYGON ((165.7799898623264 -21.08000497811563, 166.5999914899338 -21.70001881275353, 167.1200114280869 -22.15999073658349, 166.7400346214448 -22.39997608814695, 166.1897322939687 -22.12970834726045, 165.4743754417522 -21.67960662199823, 164.8298153017757 -21.14981983814195, 164.1679952334136 -20.44474659595163, 164.029605747736 -20.10564584725235, 164.4599670758627 -20.1200118954295, 165.0200362490421 -20.45999114347773, 165.4600093935751 -20.80002206795826, 165.7799898623264 -21.08000497811563))
In [9]:
countries.geometry[113]
Out:

Points

어떤 사건이 발생한 위치, 한 국가의 수도, 두 국가간의 중앙점 등은 하나의 좌표로 나타낼 수 있다. "Cities" 데이터에서는 도시를 하나의 점으로 나타내었다. 이 점을 다음처럼 지도위에 표현 할 수 있다.

In [10]:
cities.geom_type[:3]
Out:
0    Point
1    Point
2    Point
dtype: object
In [11]:
base = countries.plot(color='white', edgecolor="k")
ax = cities.plot(ax=base, marker='o', color='red', markersize=5)
ax.set_axis_off()
ax.set_title("세계 도시 분포")
plt.show()