Google Colaboratoryを使って、BODIK APIを使ったPythonプログラムを書いてみます。

課題3:BODIK APIの検索結果をPandasのデータフレームに入れる

WebAPIの実行結果をPandasのデータフレームに格納したいというケースがある。
BODIK APIの場合、どうやるのだろうか?

問題:BODIK APIの検索結果をPandasのデータフレームに格納する。

基本情報

  • Pandasは、Pythonで利用できるデータ分析のためのライブラリです。
  • 通常はCSVやExcelファイルなどを読み込んでデータフレームを作成し、データフレームを使ってデータ分析を行います。
  • 二次元配列からPandasのデータフレームを作成することができます。
  • DataFrameのコンストラクタの第一引数にデータの二次元配列、columnsに項目名の配列を指定して生成します。
  • 辞書の項目名の一覧は、辞書.keys()で取得できるが、これは配列ではない。配列にするには、list(辞書.keys())が必要です。
  • 辞書の値の一覧は、辞書.values()で取得できるが、これは配列ではない。配列にするには、list(辞書.values())が必要です。

pythonで記述

まず、BODIK APIでAEDを検索する。

import requests
import json

api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
url = f'{api_server}/{apiname}'
response = requests.get(url)
data = response.json()
features = data['resultsets']['features']
for feature in features:
  properties = feature['properties']
  print(properties)

このpropertiesを順次データフレームに入れる。

項目名の配列を作成する

まず、features(featureの配列)から先頭のfeatureをとりだし、項目名の配列を作成する。

feature_0 = features[0]
properties = feature_0['properties']
headers = list(properties.keys())

データの二次元配列を作成する

次に、propertiesの値だけの配列を作成し、親の配列に格納することで、二次元配列を作成する。

array = []
for feature in features:
  properties = feature['properties']
  values = list(properties.values())
  array.append(values)

データフレームを作成する

import pandas as pd

df = pd.DataFrame(array, columns=headers)

プログラム

まず、BODIK APIの実行結果から、項目名の配列(ヘッダー部)を作成する。

import requests
import json
import pandas as pd

api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
url = f'{api_server}/{apiname}'
response = requests.get(url)
data = response.json()
features = data['resultsets']['features']

# ヘッダー部
feature_0 = features[0]
properties = feature_0['properties']
headers = list(properties.keys())
print(headers)

次に、BODIK APIの実行結果から、データ部分を取り出す。

import requests
import json
import pandas as pd

api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
url = f'{api_server}/{apiname}'
response = requests.get(url)
data = response.json()
features = data['resultsets']['features']

# ヘッダー部
feature_0 = features[0]
properties = feature_0['properties']
headers = list(properties.keys())
print(headers)

# データ部
for feature in features:
  properties = feature['properties']
  values = list(properties.values())
  print(values)

BODIK APIの実行結果からPandasのデータフレームを作成する。データ部は2次元配列(配列の中に配列をいれたもの)にする。

import requests
import json
import pandas as pd

api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
url = f'{api_server}/{apiname}'
response = requests.get(url)
data = response.json()
features = data['resultsets']['features']

# ヘッダー部
feature_0 = features[0]
properties = feature_0['properties']
headers = list(properties.keys())

# データ部
array = []
for feature in features:
  properties = feature['properties']
  values = list(properties.values())
  array.append(values)

# データフレームを作成
df = pd.DataFrame(array, columns=headers)

# データフレームを表示する
df

BODIK APIの検索結果をPandasのデータフレームに格納することができました。この先は、Pandasを使ってデータを分析することができます。

プログラム(完成版)

コメントとエラー処理を入れて完成です。
Google Colaboratoryの場合、画面出力は最後にないとうまく表示されないので、出力部分を最後に移動させました。

import requests
import json
import pandas as pd

df = None

try:
  api_server = 'https://wapi.bodik.jp'
  apiname = 'aed'
  url = f'{api_server}/{apiname}'

  # BODIK APIを呼び出す
  response = requests.get(url, timeout=5.0)

  # APIの実行結果を確認する
  if response is not None and response.status_code == 200:
    # 結果をJSONで取得する
    data = response.json()

    # BODIK APIの検索結果を解析する
    if data is not None and 'resultsets' in data:
      resultsets = data['resultsets']
      if 'features' in resultsets:
        features = resultsets['features']
        # すくなくとも、1つのデータが必要
        if len(features) > 0:
          # ヘッダー部
          feature_0 = features[0]
          properties = feature_0['properties']
          headers = list(properties.keys())

          # データ部
          array = []
          for feature in features:
            properties = feature['properties']
            values = list(properties.values())
            array.append(values)

          # データフレームを作成
          df = pd.DataFrame(array, columns=headers)

        else:
          print('検索結果は0件')
      else:
        print('no features', resultsets)
    else:
      print('no resultsets', data)
  else:
    print('status_code', response)
    
except Exception as e:
  print('Exception', e)

# データフレームを表示する
df

お疲れ様でした。