気象データの活用は、データサイエンスや統計分析において非常に重要です。今回はNOAA(National Oceanic and Atmospheric Administration)から提供されているClimate Data Online (CDO) APIを使って、ニューヨーク市の2023年の年間気象データを取得する方法をご紹介します。
このプロジェクトでは、NOAA APIを活用して気温、降水量、降雪量、積雪量といった気象データを取得し、データをCSVファイルに保存していきます。具体的なコード例と共に、リクエスト制限の対処方法やエラーハンドリングについても解説します。
必要な準備
1. NOAA APIキーの取得
NOAA APIを利用するには、まずNOAAの公式サイトで無料のAPIキーを取得します。このAPIキーは、リクエスト送信時に使用するため、控えておきます。
ステップ1: NOAA APIの構造理解
NOAA APIは、気象観測やデータセットに関する情報を取得するための複数のエンドポイントを提供しています。以下のエンドポイントを活用して、気象データを収集します。
- /datasets:データセットの概要を取得。
- /datatypes:データの種類(例:気温や降水量など)を取得。
- /data:特定の場所と時間の気象データを取得。
特に今回は、/dataエンドポイントを使用して、ニューヨーク市の2023年の気象データを日ごとに取得していきます。
ステップ2: データの取得
NOAA APIには、「1秒あたり5件まで、1日あたり10,000件まで」というリクエスト制限があります。そのため、データを取得する際は以下のような工夫が必要です。
実装方法
- リクエスト間隔の設定:1秒に1リクエストを目安にするため、
time.sleep()
でリクエスト間隔を空ける。 - エラーハンドリング:タイムアウトやAPI制限エラーに対する処理を組み込みます。
使用するデータ項目
2023年の年間データとして以下の項目を取得します:
- 日最高気温 (
TMAX
) - 日最低気温 (
TMIN
) - 降水量 (
PRCP
) - 降雪量 (
SNOW
) - 積雪量 (
SNWD
)
プロジェクト概要
このプロジェクトでは、NOAA APIを用いて2023年のニューヨーク市の気象データ(気温、降水量、降雪量、積雪量)を取得し、CSVファイルに保存します。具体的には、データ取得の際のリクエスト制限対策やエラーハンドリングも考慮しています。
ライブラリのインポートと基本設定
まず、リクエスト処理と時間管理に必要なライブラリrequests
とtime
をインポートします。加えて、取得したデータをCSVファイルとして保存するためのcsv
もインポートします。
1 2 3 |
import requests import csv import time |
NOAA APIキーの設定
NOAA APIの使用にはAPIキーが必要です。ここで取得したAPIキーを設定し、headers
に含めてリクエストの際に送信します。
1 2 3 4 5 6 7 |
# NOAA APIキー api_key = '自分のAPIキーを入力してください' # 自分のAPIキーを入力してください # APIリクエストヘッダーにAPIキーを含める headers = { 'token': api_key } |
リクエスト間隔とエラーハンドリングを含むデータ取得関数の定義
NOAAのAPIにはリクエスト制限があるため、1秒ごとにリクエストを送信するように設定しています。また、エラーハンドリングのため、レート制限やタイムアウトが発生した場合は、リクエストを再試行する処理を追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# リクエスト間隔(1秒に1リクエストを目安に設定) REQUEST_INTERVAL = 1.0 # データを取得する関数 def fetch_data(params, headers): base_url = 'https://www.ncei.noaa.gov/cdo-web/api/v2/data' try: # データをリクエスト response = requests.get(base_url, headers=headers, params=params, timeout=10) # レート制限に達した場合の再試行 if response.status_code == 429: print("リクエスト制限に達しました。しばらく待って再試行します。") time.sleep(REQUEST_INTERVAL) return fetch_data(params, headers) # その他のエラーチェック elif response.status_code != 200: print(f"エラー: {response.status_code}") return None # 正常に取得できた場合はJSON形式で返す return response.json() # タイムアウトエラーが発生した場合の再試行 except requests.exceptions.Timeout: print("タイムアウトが発生しました。再試行します。") time.sleep(REQUEST_INTERVAL) return fetch_data(params, headers) |
CSVファイルの初期化
ここで、取得したデータを保存するCSVファイルを準備し、ヘッダー行を書き込みます。ヘッダーには、日付、最高気温、最低気温、降水量、降雪量、積雪量の各項目が含まれています。
1 2 3 4 |
# CSVファイルの初期化 with open('noaa_weather_data_2023_full.csv', mode='w', newline='', encoding='utf-8') as file: writer = csv.writer(file) writer.writerow(['日付', '日最高気温', '日最低気温', '降水量', '降雪量', '積雪量']) |
月ごとにデータを取得してCSVに書き込む
NOAAのAPIでは一度に取得できるデータ量が制限されているため、月ごとにデータを取得します。各月ごとにstart_date
とend_date
を設定し、NOAA APIにリクエストを送信します。
コード内でのリクエスト設定とデータ取得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# 月ごとにリクエストを送信 for month in range(1, 13): # 開始日と終了日の設定 start_date = f"2023-{month:02d}-01" end_date = f"2023-{month:02d}-31" if month in [1, 3, 5, 7, 8, 10, 12] else \ f"2023-{month:02d}-30" if month in [4, 6, 9, 11] else "2023-02-28" # 1000件ずつオフセットを増加させて取得 offset = 1 while True: # リクエストパラメータ設定 params = { 'datasetid': 'GHCND', # Daily Summaries 'locationid': 'CITY:US360019', # ニューヨーク市のID 'startdate': start_date, 'enddate': end_date, 'units': 'metric', 'datatypeid': ['TMAX', 'TMIN', 'PRCP', 'SNOW', 'SNWD'], # 必要なデータタイプ 'limit': 1000, 'offset': offset } # データの取得 data = fetch_data(params, headers) # データが取得できなかった場合はループを終了 if not data or 'results' not in data: break |
データの整理とCSVへの書き込み
APIから取得したデータを日付ごとに整理し、各データ項目(例:TMAX、TMINなど)を対応するCSV列にマッピングして書き込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# 日付ごとのデータを辞書にまとめる daily_data = {} for record in data['results']: date = record['date'][:10] datatype = record['datatype'] value = record['value'] if date not in daily_data: daily_data[date] = {} daily_data[date][datatype] = value # CSVに書き込み for date, values in daily_data.items(): writer.writerow([ date, values.get('TMAX', 'NA'), # 日最高気温 values.get('TMIN', 'NA'), # 日最低気温 values.get('PRCP', 'NA'), # 降水量 values.get('SNOW', 'NA'), # 降雪量 values.get('SNWD', 'NA') # 積雪量 ]) # オフセットを増加させて次のデータを取得 offset += 1000 time.sleep(REQUEST_INTERVAL) # リクエスト間隔を置く print(f"{month}月のデータ取得完了") print("2023年分のデータがnoaa_weather_data_2023_full.csvに保存されました。") |
まとめ
このコードにより、2023年のニューヨーク市の気象データをAPIから取得し、CSV形式で保存することができます。データ取得後は、Pandasなどを使ってデータの前処理や分析を行うことも可能です。この方法を使うことで、他の都市や期間のデータ取得にも応用ができます。
Pythonを学びたい方はこちらの記事を参考にしてみてください
関連記事
プログラミング学習を進めているけれど、まだ副収入につなげられていない…そんなあなたへ!今こそ、学んだスキルを活かして副業に挑戦する絶好のチャンスです。プログラミングだけでなく、自分のスキルや商品をネットで販売する『ネットショップ』を開設してみませんか?
ネットショップを持つことで、自分の知識やスキルをより多くの人に届け、副収入を得ることが可能です。学んできたプログラミングを活かして、ショップのカスタマイズや運営も自由自在に行えますし、もし商品作成が難しい場合でも、デジタル商品やサービス提供など、いろんな選択肢があります。
このステップで一歩踏み出せば、今学んでいることが副収入に直結し、自分の時間をより有効に使うことができるはずです!一緒にネットショップを開設し、副業の第一歩を踏み出しましょう!
タイトルテキスト
プログラミングを学びたいけど、どこから始めたらいいのか分からない、自分に合っているか不安…そんな悩みを持っている方におすすめしたいのが、 無料相談 サービスです!
この無料相談では、あなたの現状や目標に合わせて、最適な学習プランを一緒に考えてくれます。どんなスキルが必要なのか、どうやって学習を進めると効果的かを具体的にアドバイスしてもらえるので、無駄なく効率的にスタートを切ることができます。
さらに、プログラミング学習には同じ目標を持つ 仲間 がいること、そして頼りになる メンター の存在がとても大きな支えになります。独学ではどうしてもつまずきやすい部分も、メンターがあなたの成長に合わせて親身にサポートしてくれるので、安心して学びを進められます。
まずは 無料相談 で、あなたに合ったプランを見つけて、スキルアップへの第一歩を踏み出してみませんか?今なら、迷っている方でも気軽に相談できるチャンスです!