はじめての気象データ処理

このブログでは、気象を学ぶ方でも超初心者を対象として気象データ解析のための基礎基本を解説します。主にFORTRAN、Python、GMT、GrADSのTipsをご紹介します。

気象庁アメダス10分間値をダウンロードする方法

みなさんこんにちは。おこめまんです。

 

今回は、「気象庁アメダス10分間値をダウンロードする方法」という内容でやっていきたいと思います。

はじめに

気象庁のサイトの「各種データ・資料」に「過去の気象データ・ダウンロード」という欄があるかと思いますが、「10分間値が欲しいのに時別値までしかダウンロードできないの!?」となっている方がいらっしゃるかと思います。

 

当方も同じようなことを思っていたのですが、「スクレイピング」という技術を使うことにより、気象庁からデータをダウンロードすることができるということでやってみました。

これは、プログラムで気象庁の「過去の気象データ検索」のデータがほしいページにアクセスして10分間値の表のデータを抜き取るというものです。

大間アメダスのデータをゲットする

今回は青森県大間アメダスのデータを持ってくることにします。

「過去の気象データ検索」で2018年1月1日の大間アメダス10分間値を開いてみましょう。

http://www.data.jma.go.jp/obd/stats/etrn/view/10min_a1.php?prec_no=31&block_no=1041&year=2018&month=1&day=1&view=

このURLを開くと該当ページが開くかと思います。イメージ的には、スクレイピングでこのページに日付を変えて何度もアクセスしてデータを持ってくる感じです。

ちなみに

prec_no=31

block_no=1041

のところを自分が欲しい地点に合わせて変えましょう。

 

とりあえず、青森県大間の2018年1月の1か月分のデータを持ってくるプログラムを見てみましょう。

このコードでは、1か月分の持ってきたデータを1つのcsvファイル中に保存しています。 

使用した言語

Python3.7.3

 

※注意

Pythonは先頭の空白にも意味があります。ループ処理をする際には特に注意してください。

Pythonコード

##### ライブラリの読み込み #####
from datetime import datetime
import numpy as np
import pandas as pd
import time

 

##### 日付を指定 #####
ylist=[2018]  # yearの指定
mlist=[1]  # monthの指定

 

for k in ylist :

 for j in mlist:
  for i in range (1, 32) :  # --- 日ループ
   year = k
   month = j
   day = i
   print('get_data --->',k,'/', j,'/', i)


   ##### urlを指定#####
  url = 'http://www.data.jma.go.jp/obd/stats/etrn/view/10min_a1.php?prec_no=31&block_no=1041&year=' + str(year) + '&month=' + str(month) + '&day=' + str(day) + '&view=p1'


   ##### スクレイピング #####
   tables = pd.io.html.read_html(url)
   df = tables[0].iloc[:,1:] # --- 必要な行と列を抽出
   df = df.reset_index(drop = True)

 

   ##### 列名を指定 #####
   df.columns = ['PRC', 'TEMP', 'WS_MEAN', 'WD_MEAN', 'WS_GUST', 'WD_GUST', 'SUN']

 

   ##### 欠測値の処理 #####
   df = df.replace('///', '-999.9') # --- '///' を欠測値として処理
   df = df.replace('×', '-999.9') # --- '×' を欠測値として処理
   df = df.replace('\s\)', '', regex = True) # --- ')' が含まれる値を正常値として処理
   df = df.replace('.*\s\]', '-999.9', regex = True) # --- ']' が含まれる値を欠測値として処理
   df = df.replace('#', '-999.9') # --- '#'が含まれる値を欠測値として処理
   df = df.replace('--', '-999.9') # --- '--'が含まれる値を欠測値として処理
   df = df.fillna(0) # --- NaN を欠測値として処理

 

   ##### 風向を北0°で時計回りの表記に変更 #####
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('北北東', '22.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('東北東', '67.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('東南東', '112.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('南南東', '157.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('南南西', '202.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('西南西', '247.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('西北西', '292.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('北北西', '337.5')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('北東', '45.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('南東', '135.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('南西', '225.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('北西', '315.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('北', '360.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('東', '90.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('南', '180.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('西', '270.0')
   df.loc[:,['WD_MEAN', 'WD_GUST']] = df.loc[:,['WD_MEAN', 'WD_GUST']].replace('静穏', '-888.8')

 

   ##### 時刻列を追加 #####
   df['DATE'] = pd.date_range(datetime(year, month, day, 0, 10, 0), periods = len(df), freq = '10T')

 

   ##### 年/月/日/時/分/秒 の各列を追加 #####
   df['YEAR'] = df['DATE'].dt.year
   df['MONTH'] = df['DATE'].dt.month
   df['DAY'] = df['DATE'].dt.day
   df['HOUR'] = df['DATE'].dt.hour
   df['MINUTE'] = df['DATE'].dt.minute
   df['SECOND'] = df['DATE'].dt.second

 

   ##### 処理の停止時間を指定 #####
   time.sleep(1)

 

   ##### csvファイルとして出力 #####
   if i == 1:
   df.to_csv(
   'amd10_31001_'+str(year)+(str(month).zfill(2))+'.csv', \
   columns = ['YEAR', 'MONTH', 'DAY', 'HOUR', 'MINUTE','SECOND', 'PRC', 'TEMP', \         'WS_MEAN', 'WD_MEAN', 'WS_GUST', 'WD_GUST', 'SUN'], \
   header = False, index = False
   )
   else:
   df.to_csv(
   'amd10_31001_'+str(year)+(str(month).zfill(2))+'.csv', \
   columns = ['YEAR', 'MONTH', 'DAY', 'HOUR', 'MINUTE','SECOND', 'PRC', 'TEMP',  \       'WS_MEAN', 'WD_MEAN', 'WS_GUST', 'WD_GUST', 'SUN'], \
   header = False, index = False, mode = 'a'
   )

exit()

最後に

このコードを自身のディレクトリ内に保存して、実行してみましょう。

おそらく「amd10_31001_201801.csv」というファイルができるはずです。

コード中のオレンジ色の 部分を自分の欲しい地点、期間に変更して使いましょう。

ylist, mlistには、複数の値を入れることができます。

例えば、

ylist=[2014, 2018]

mlist=[1, 3 ,5]

とすれば、2014年1月、3月、5月、2018年1月、3月、5月のデータをゲットできるはずです。

このとき、1か月30日の月と、1か月31日の月などを一緒に書くとうまくいきません。

mlist=[1, 2, 4]  ×

mlist=[1, 3 ,5 ,7 ,8] 〇

のように分けてプログラムを動かしましょう。

なお、気圧、相対湿度を観測している地点は列を追加する必要があるので注意してください。

 

いかがでしたでしょうか。ぜひ、これを参考にアメダスデータを解析してみてください。