Pandasで外部APIからデータを取得し整形

プログラミング

Pandasを用いた外部APIからのデータ取得と整形

Pandasライブラリは、Pythonにおけるデータ分析の強力なツールであり、外部APIから取得したデータを効果的に処理・整形するために不可欠です。本稿では、Pandasを用いて外部APIからデータを取得し、それを分析に適した形に整形するプロセスについて、その詳細と実践的な側面を解説します。

1. 外部APIからのデータ取得

外部APIからデータを取得する際には、まずAPIの仕様を理解することが重要です。APIエンドポイントのURL、必要な認証情報(APIキー、トークンなど)、リクエストメソッド(GET、POSTなど)、およびリクエストパラメータを確認します。PythonでAPIリクエストを行うには、主にrequestsライブラリが使用されます。

1.1. requestsライブラリの活用

requestsライブラリは、HTTPリクエストを非常に簡単に行えるように設計されています。基本的なGETリクエストは、以下のようなコードで実行できます。

import requests

api_url = "https://example.com/api/data"
response = requests.get(api_url)

APIによっては、リクエストヘッダーに認証情報を含める必要があります。

headers = {
    "Authorization": "Bearer YOUR_API_KEY"
}
response = requests.get(api_url, headers=headers)

POSTリクエストの場合、リクエストボディにデータを送信します。

payload = {
    "param1": "value1",
    "param2": "value2"
}
response = requests.post(api_url, json=payload)

APIからのレスポンスは、通常JSON形式で返されます。これをPythonの辞書やリストに変換するには、response.json()メソッドを使用します。

data = response.json()

APIリクエストが成功したかどうかは、response.status_codeで確認できます。一般的に、200番台のステータスコードは成功を示します。エラーハンドリングは、API連携において非常に重要であり、例外処理(try-exceptブロック)を用いて、ネットワークエラーやAPIからのエラーレスポンスに対応します。

1.2. ページネーションへの対応

多くのAPIは、一度に返されるデータ量に制限があるため、ページネーション(データの分割取得)を実装しています。APIのドキュメントを確認し、どのパラメータ(例: page、limit、offset)がページネーションに使用されているかを把握します。一般的には、ループ処理を用いて、全てのページからデータを取得します。

all_data = []
page = 1
while True:
    params = {"page": page}
    response = requests.get(api_url, params=params)
    current_page_data = response.json()

    if not current_page_data: # データがなくなったらループを抜ける
        break

    all_data.extend(current_page_data)
    page += 1

2. Pandasによるデータ整形

APIから取得したデータは、そのままでは分析に適さない場合が多いです。PandasのDataFrame構造に変換し、クリーニング、変換、結合などの操作を行います。

2.1. DataFrameへの変換

APIから取得したJSONデータが、リスト形式や辞書形式であれば、直接PandasのDataFrameに変換できます。

import pandas as pd

# JSONデータがリスト形式の場合
list_data = [{"col1": 1, "col2": "A"}, {"col1": 2, "col2": "B"}]
df = pd.DataFrame(list_data)

# JSONデータが辞書形式で、各キーが列名となる場合
dict_data = {"col1": [1, 2], "col2": ["A", "B"]}
df = pd.DataFrame(dict_data)

JSONデータがネストしている場合(入れ子構造になっている場合)、pd.json_normalize()関数が非常に役立ちます。この関数は、ネストしたJSONデータをフラットなDataFrameに変換してくれます。

nested_data = [
    {"id": 1, "user": {"name": "Alice", "age": 30}},
    {"id": 2, "user": {"name": "Bob", "age": 25}}
]
df = pd.json_normalize(nested_data, sep="_") # sepでネストしたキーの区切り文字を指定
print(df)
# 出力例:
#    id       user_name  user_age
# 0   1           Alice        30
# 1   2             Bob        25

2.2. データクリーニング

APIから取得したデータには、欠損値(NaN)、不要な文字、フォーマットの不一致などが含まれることがあります。

  • 欠損値の処理: df.isnull().sum()で欠損値の数を確認し、df.dropna()で欠損値を含む行や列を削除したり、df.fillna()で特定の値で補完したりします。
  • データ型の変換: df[‘column’].astype(new_type)を用いて、数値型、文字列型、日付型などに変換します。特に日付データは、pd.to_datetime()で正確にパースすることが重要です。
  • 不要な文字の削除: 文字列型の列に対して、df[‘column’].str.replace()やdf[‘column’].str.strip()などを用いて、不要な文字(例: 空白、特殊文字)を削除します。
  • 重複データの削除: df.drop_duplicates()で重複行を削除します。

2.3. 特徴量エンジニアリング

分析の目的に応じて、既存の列から新しい列を作成する特徴量エンジニアリングを行います。

  • 計算結果の追加: 複数の列を組み合わせて新しい列を作成します。例えば、売上データから利益率を計算するなど。
  • カテゴリ変数のエンコーディング: 機械学習モデルに投入するために、カテゴリ変数を数値に変換します(例: One-Hot Encoding)。pd.get_dummies()が便利です。
  • 日付/時刻データの加工: 日付列から年、月、日、曜日などを抽出し、新しい列として追加します。

2.4. データの結合と集計

複数のAPIから取得したデータを統合したり、特定の条件でデータを集計したりすることも一般的です。

  • 結合: pd.merge()関数やdf.join()メソッドを用いて、共通のキー列を持つDataFrameを結合します。
  • 集計: df.groupby()メソッドを用いて、特定の列の値に基づいてデータをグループ化し、合計、平均、カウントなどの集計処理を行います。

3. 実践的な考慮事項

3.1. エラーハンドリングとロギング

API連携は、ネットワークの不安定さやAPI側の仕様変更など、予期せぬエラーが発生しやすい処理です。

  • APIリクエストにおけるtry-exceptブロックの活用は必須です。具体的には、requests.exceptions.RequestExceptionなどの例外を捕捉します。
  • APIからのエラーレスポンス(例: 4xx、5xxステータスコード)も適切に処理し、エラーメッセージを記録(ロギング)することで、問題発生時のデバッグを容易にします。Pythonのloggingモジュールが利用できます。

3.2. APIレート制限への配慮

多くのAPIには、一定時間内に送信できるリクエスト数に制限(レート制限)があります。この制限を超えると、一時的にアクセスできなくなったり、ペナルティを受けたりする可能性があります。

  • APIドキュメントでレート制限に関する情報を確認します。
  • リクエスト間に適切な遅延(time.sleep())を設けることで、レート制限に抵触するリスクを低減します。
  • 必要であれば、リクエストキューイングやバックオフ処理(エラー発生時に指数関数的に待機時間を増やす)などの高度な戦略を実装します。

3.3. データ量の管理

取得するデータ量が多い場合、メモリ不足や処理時間の増大が問題となることがあります。

  • 一度に全てのデータを取得するのではなく、ページネーションを適切に利用します。
  • Pandas DataFrameのメモリ使用量を削減するために、不要な列を削除したり、データ型を最適化したりします(例: int64をint32にする)。
  • 必要に応じて、データをディスクに一時保存したり、バッチ処理を行ったりすることを検討します。

3.4. APIキーや認証情報の管理

APIキーなどの認証情報は機密情報です。コード内に直接記述せず、環境変数や設定ファイルから読み込むようにします。

  • python-dotenvライブラリなどを利用して、.envファイルから環境変数を読み込むのが一般的です。

まとめ

Pandasとrequestsライブラリを組み合わせることで、外部APIからデータを取得し、それを分析可能な形に整形する一連のプロセスを効率的に実行できます。APIの仕様理解、適切なリクエスト方法、そしてPandasを用いた柔軟なデータ操作が、データ分析の成功の鍵となります。エラーハンドリング、レート制限への配慮、データ量の管理といった実践的な考慮事項を怠らずに実装することで、堅牢で信頼性の高いデータパイプラインを構築することができます。