오늘 할 일: 끝내주게 숨쉬기
article thumbnail

최근 좌표를 포함하는 데이터를 전처리하면서 geopandas라는 라이브러리를 접하게 되어, 사용방법을 간단하게 포스팅하고자 한다.

 

GeoPandas

https://geopandas.org/en/stable/

 

GeoPandas 0.12.0 — GeoPandas 0.12.0+0.g31f8e6a.dirty documentation

GeoPandas 0.12.0 GeoPandas is an open source project to make working with geospatial data in python easier. GeoPandas extends the datatypes used by pandas to allow spatial operations on geometric types. Geometric operations are performed by shapely. Geopan

geopandas.org

geopandas는 파이썬에서 지역과 관련된 좌표 정보를 쉽게 처리하기 위해 개발된 오픈 소스이다. tabular 데이터를 처리하는 데에 필수 라이브러리인 pandas를 확장하여서 라이브러리 이름에 pandas를 포함하고 있다. 또한 shapely라는 기하학적 객체를 다루는 라이브러리와 함께 주로 사용된다.

 

from shapely.geometry import Polygon, MultiPolygon, Point
import geopandas as gpd
import matplotlib.pyplot as plt

 

 

[contains] Polygon 내 특정 좌표 유무 확인

 

geopandas의 GeoSeries, GeoDataFrame은 pandas의 Series, DataFrame과 유사하다. GeoSeries, GeoDataFrame가 좌표나 영역 같은 지리 정보를 받는다는 차이가 있다. shapely의 Polygon을 이용하여 다각형 객체를 만들고 GeoSeries에 저장하고, 특정 좌표가 다각형 내에 속하는지 확인해보자.

s1 = gpd.GeoSeries(
    [
        Polygon([(0, 0), (2, 0), (2, 4), (0, 4)]),
        Polygon([(1, 1), (5, 1), (3, 6), (1, 6)]),
        Polygon([(1, 0), (2, 1), (3, 5), (0, 6)]),
        Polygon([(3, 2), (5, 5), (2, 5), (1, 4)]),
    ],
    index=range(4),
)
for idx in range(4):
    x, y = s1[idx].exterior.xy 
    plt.plot(x, y, label=str(idx))
    plt.legend()
plt.plot(1, 1, marker="o", color="purple")

 

4가지 다각형 내에 좌표 (1, 1)이 포함되는지 여부를 확인하기 위해서는 contains 메소드를 사용한다.

point = Point(1, 1)
s1.contains(point)

1, 3번째 다각형에는 좌표 (1, 1)이 속해 있고, 4번째 다각형에는 속하지 않음을 확인할 수 있다. 좌표가 다각형 라인에 걸쳐있는 경우에 False를 반환한다.

 

 

[distance] 1) Polygon과 좌표 사이의 가장 가까운 거리 측정

 

위에서 만들었던 다각형들과 좌표 (1, 1) 사이에 가장 가까운 거리의 길이를 측정하기 위해 distance 메소드를 사용한다. 거리 측정을 위해 다각형을 테두리 단위로 분리하는 boundary 속성을 사용하고, 이후 distance 메소드를 적용한다.

 

s1.boundary.distance(
	gpd.GeoSeries([Point(1, 1) for _ in range(4)]))

 

boundary 없이 distance 메소드를 사용하게 되면, 다각형 안에 좌표가 있는 경우는 거리를 측정하지 않게 된다.

s1.distance(
    gpd.GeoSeries([Point(1, 1) for _ in range(4)]))

 

 

[distance] 2) 위도, 경도를 이용한 직선 거리 계산

 

실제 위도, 경도 좌표를 이용하여 좌표간 거리를 계산해보자. 아래는 구글 지도를 통해 얻은 63빌딩과 국회의사당, 장충체육관과 남산서울타워의 좌표이다.

 

 

coor1 = gpd.GeoDataFrame({'geometry': [
    Point(126.9403139, 37.5198158), # 63빌딩
    Point(127.0067900, 37.5581865)  # 장충체육관 
]}, crs='EPSG:4326')
coor2 = gpd.GeoDataFrame({'geometry': [
    Point(126.9142029, 37.5319170), # 국회의사당
    Point(126.9878822, 37.5510548)  # 남산서울타워
]}, crs='EPSG:4326')

display(coor1, coor2)

 

crs는 좌표계(Coordinate reference systems)로, 지구 위 위치 정보를 2차원 평면에 표현하는 방법론을 의미한다. 좌표계를 다르게 적용하면 거리나 위치가 다르게 표현될 수 있어 반드시 동일하게 맞춰야 한다. EPSG:4326은 GPS가 사용하는 좌표계(위도와 경도)이다.

 

coor1.to_crs(epsg=3310, inplace=True)
coor2.to_crs(epsg=3310, inplace=True)
coor1.distance(coor2)

 

63빌딩과 국회의사당, 장충체육관과 남산서울타워의 미터 단위로 직선거리를 계산하기 위해, 좌표계를 변경한 후 distance 메소드를 적용한다. 구글 지도에서 거리 측정을 해보면 결과와 동일한 것을 확인할 수 있다.

 

남산타워 ~ 장충체육관 거리

 

 

[sjoin] Polygon 내에 속하는 좌표와 조인하기

 

다각형 내에 특정 좌표가 속해있을 때 그와 관련된 정보를 조인을 통해 가져올 수도 있다. Polygon 정보가 있는 데이터프레임과 Point 정보가 있는 데이터프레임을 spatial join하여 내용을 확인해보자.

 

cities = gpd.read_file(gpd.datasets.get_path("naturalearth_cities"))
display(cities.shape, cities.head())

countries = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
display(countries.shape, countries.head())

 

geopandas에서 샘플로 제공하는 도시 정보와 나라 정보를 로드했다. 

 

display(cities[cities["name"] == "Seoul"],
        countries[countries["name"] == "South Korea"],
)

 

cities 데이터프레임에는 도시마다 위도, 경도 좌표 정보가 있고, countires 데이터프레임에는 나라마다 polygon으로 영역 정보가 저장되어 있다. 각 데이터프레임에서 지리 정보는 geometry라는 동일한 컬럼으로 관리된다. 기본적으로 geopandas는 지리 정보들을 geometry라는 컬럼에 저장하고 내부 메소드들도 geometry에 적용되는 것 같다.. 

 

cities_w_country_data = gpd.sjoin(cities, countries, how="inner")  
cities_w_country_data

 

두개의 GeoDataFrame은 sjoin 메소드를 통해 조인할 수 있다. cities에 있는 도시 좌표가 countries에 있는 특정 나라의 영역 좌표에 속하게 되면, 해당하는 나라의 부가 정보들(인구 수, 대륙, 나라 이름 등)을 붙이는 식이다.

 

cities_w_country_data[cities_w_country_data["name_left"] == "Seoul"]

 

 

참고

 

https://geopandas.org/en/stable/docs/user_guide.html

 

User Guide — GeoPandas 0.12.1+0.g195f70b.dirty documentation

 

geopandas.org

https://datascienceschool.net/03%20machine%20learning/03.04.01%20%EC%A7%80%EB%A6%AC%20%EC%A0%95%EB%B3%B4%20%EB%8D%B0%EC%9D%B4%ED%84%B0%20%EC%B2%98%EB%A6%AC.html

 

지리 정보 데이터 처리 — 데이터 사이언스 스쿨

GeoPandas는 파이썬에서 지리정보 데이터 처리의 기하하적 연산과 시각화 등을 돕는 패키지이다. 이름으로도 알 수 있듯이, GeoPandas는 Pandas와 비슷하다. 두 가지의 자료형 GeoSeries와 GeoDataFrame이 있

datascienceschool.net

https://gis.stackexchange.com/questions/293310/how-to-use-geoseries-distance-to-get-the-right-answer

 

How to use GeoSeries.distance to get the right answer

When I want the distance between two points [(117.454361,38.8459879),(117.459880 ,38.846255)] (longitude,latitude) on the earth, I take the GeoSeries.distance method, but the method does not give m...

gis.stackexchange.com