ishii-akihiro’s blog

いろいろ試したことやバグ対応の作業履歴を残していきます。

ArcGISのテーブル属性をpythonで加工してcsv出力する

概要

最近GISデータの属性値をExcelに出力して集計する作業が多いのですが、
元データの修正が必要になるとExcel出力からやり直すのが面倒です。
あと、属性の種類が多いと対象の属性を探すのも大変です。

そこで、以下の作業をmxdやaprxファイルを開かずにpythonで実行してみます。

  1. GDBに保存されたフィーチャクラスのテーブル属性読み込み
  2. データ抽出・加工
  3. csv出力

環境

  • Windows 10
  • ArcGIS Pro 2.1(Proでなくても、mxdでGDBに保存したフィーチャクラスがあれば多分OK)
  • python 3系(※)
  • numpy(※)
  • pandas(※)
  • Jupyter Notebook(※)

(※)ArcGIS Pro 2.1以降は自動でインストールされるようです。Anacondaをインストールしてもよいですが、よくわからない方は Pro のバージョンを2.1にアップグレードするのが簡単だと思います。

前提

Jupyter Notebook を使用できること

あまり知らない方はこちらの記事の手順を参考にしてください。
ArcGIS Pro のgdbを Pythonで操作する - ishii-akihiro’s blog

使用するデータ

GDBのデータがあれば何でもよいです。

本記事ではestatから国勢調査の小地域ポリゴンをダウンロードして使います。
新潟県長岡市のデータだけ抽出して、
PracticeArcpy.gdbに「Nagaoka」フィーチャクラスとして保存しています。
統計GISデータダウンロード | 政府統計の総合窓口

手順

1. Jupyter Notebookを起動し、GDBと同じフォルダに移動する。

2. 右上の「New」>「Python3」を選択して新規ノートブックを開く。f:id:ishii-akihiro:20180729095405p:plain

3. 必要な属性をGDBから抽出し、データフレームに格納する。

以下、新規ノートブック上での作業手順です。
arcpyライブラリで直接データフレームに変換する関数が見当たらないため、
いったんNumPyArrayに変換してからデータフレームに変換します。

import arcpy
import numpy
import pandas as pd

# 対象とするフィーチャクラスのパスを指定
input = "PracticeArcpy.gdb/Nagaoka"

# 4属性('KEY_CODE', 'MOJI', 'JINKO', 'SETAI')のデータをNumPyArray形式で取得
arr = arcpy.da.FeatureClassToNumPyArray(input, ('KEY_CODE', 'MOJI', 'JINKO', 'SETAI'))

# NumPyArray形式から、Pandasのデータフレーム形式に変換
df = pd.DataFrame(arr)

# データフレームに変換したデータを表示
df

f:id:ishii-akihiro:20180729100327p:plain

4. 必要なデータや属性を抽出する(必要であれば)。

# 一部の属性を抽出(※複数の場合は、[]を2重にする)
df[['MOJI', 'JINKO']]

f:id:ishii-akihiro:20180729100949p:plain

# JINKOが2,000人以上のデータのみ抽出
df[df.JINKO > 2000]

f:id:ishii-akihiro:20180729101017p:plain

# JINKOが2,000人以上のデータの'MOJI','JINKO'のみ抽出
df[['MOJI', 'JINKO']].query('JINKO >= 2000')

f:id:ishii-akihiro:20180729101024p:plain

5. データフレームに新たな列を追加し、既存の属性から算出した値を入力する。

# データを加工するため、新規データフレーム df2 にコピー
df2 = df.copy()

#「人口2000人以上フラグ」列を追加(存在しない列名を指定すると、新たな列として追加される)
df2['人口2000人以上フラグ'] = 0

# JINKOが2,000人以上のデータにフラグを立てる(df.loc[編集対象行の抽出条件, 対象列名] = 代入する値)
df2.loc[df2['JINKO'] >= 2000, '人口2000人以上フラグ'] = 1

# フラグ確認のため、JINKOが多い順にソートして表示
df2.sort_values(by=['JINKO'], ascending=False)

f:id:ishii-akihiro:20180729101039p:plain

6. csvに出力する。

# csvに出力
df2.to_csv("長岡市人口.csv")

まとめ

GISデータを修正した後に、同じ手順で再集計を簡単に実施できるようになったと思います。
mxdやaprx上で手作業するよりも、作業ミスと確認漏れの軽減が図れそうです。

手順3でGDBのテーブル属性をPandasのデータフレームに変換してしまえば、
Web上の参考情報でだいたいの集計・加工はできると思います。

追記(2018/7/31)

手順3ですべてのフィールドを抽出する場合は、
こちらの記事の解決方法をご覧ください。
データタイプが「Geometry」のフィールドは除外する必要があります。
arcpy で Exception: Data must be 1-dimensional が出た - ishii-akihiro’s blog