12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

GeoPandasで空間結合を行い、ポリゴン内に含まれるポイントの属性情報をポリゴンの属性にカンマ区切りで付与する

Posted at

はじめに

PythonのGeoPandasライブラリは、地理空間データの操作を効率的に行えます。
ArcGISやQGISなどでデータ処理するより、高速(であることが多い)かつ履歴が残るため、私は好んで使用しています。
今回は、GeoPandasを使って以下の処理をしてみます。

  • ①行政界ポリゴンと②学校ポイントを準備する
  • 各行政界に存在する学校の名前を把握する
    • ①行政界ポリゴンに新しく属性を追加し、対象の行政界に含まれる②学校の名前をカンマ区切りで入力する

使用したPythonとGeoPandasのバージョンは以下の通りです。
Python: 3.10.9
GeoPandas: 0.9.0

データの準備

今回使用するデータは、国土数値情報ダウンロードサイトから群馬県のデータをダウンロードして使用します。

コード

必要なライブラリのインポート

python
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt

データの読み込みと確認

行政界のポリゴンデータを読み込みます。

python
admin_area = gpd.read_file("data/N03-20230101_10_GML/N03-23_10_230101.shp", encoding="shift-jis")
admin_area.head()

image.png

学校のポイントデータを読み込みます。

python
school_point = gpd.read_file("data/P29-21_10_GML/P29-21_10.shp", encoding="shift-jis")
school_point.head()

image.png

データをプロットして確認する

それぞれのデータの位置関係を確認してみます。

python
fig, ax = plt.subplots(figsize=(10, 10))
admin_area.plot(ax=ax)
school_point.plot(ax=ax, color="red", markersize=1)

image.png

2つのデータを空間結合する

行政界ポリゴンと学校ポイントはgeopandas.sjoin関数を使って、空間結合させます。
https://geopandas.org/en/stable/docs/reference/api/geopandas.sjoin.html

sjoin関数の特徴は以下の通りです。

  • pandasのmerge関数とほぼ同じように使用できる
  • 引数のopに空間的位置関係を指定する(GeoPandasのバージョンによってはopではなくpredicate
  • opのデフォルト値はintersects

GeoPandasのドキュメントを参照すると、 opで指定できる空間的位置関係は以下の通りです。

  • contains
  • within
  • touches
  • crosses
  • overlaps

以上を踏まえ、行政界ポリゴンと学校ポイントを空間結合します。
空間結合した後は、groupby関数を活用しつつ、学校の名前を行政界単位でまとめます。
まとめた結果をmerge関数を使って行政界ポリゴンに結合させて完成です。

python
# 行政界ポリゴンと学校の間の空間結合を行う
admin_with_schools = gpd.sjoin(admin_area, school_point, how='left', op='contains')

# 学校の名前をカンマ区切りで結合する
schools_by_admin = admin_with_schools.groupby('OBJECTID')['P29_004'].apply(lambda x: ', '.join(x.dropna())).reset_index()

# 行政界ポリゴンの任意の列に学校の名前を入力する
admin_area['school_names'] = admin_area.merge(schools_by_admin, left_on='OBJECTID', right_on='OBJECTID', how='left')['P29_004']

# 結果を表示する
admin_area.head()

image.png

処理した結果の確認

処理した結果をQGISで確認してみます。
上手に処理できました!!
image.png

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?