気象庁ホームページのの過去のアメダスデータから、Pythonでデータを取り出すことを考える。例として福岡県八幡の1983年の月ごとの値のページの合計降水量を取得してみる。
Pythonでデータを取り出す(スクレイピングする)方法は色々あるが、ここではpandasのread_htmlを使って簡単にやってしまおう。HTMLを解析する必要はない。
padasを読み込む。
import pandas as pd
URLはこれ。
url="https://www.data.jma.go.jp/obd/stats/etrn/view/monthly_a1.php?prec_no=82&block_no=0780&year=1983&month=&day=&view="
read_htmlを使う。これでWeb内のテーブルが読み込める。
table=pd.read_html(url)
出力はリストで2つ内容が入っていることがわかる。
print(type(table))
print(len(table))
<class 'list'>
2
1番目の中身。
print(table[0])
月 降水量(mm) 気温(℃) 風向・風速(m/s) \
月 合計 日最大 最大 平均 最高 最低 平均風速
月 合計 日最大 1時間 10分間 日平均 日最高 日最低 最高 最低 平均風速
0 1 65 22 9 /// 5.9 9.1 2.6 15.9 -1.0 2.4
1 2 84 22 10 /// 5.0 8.2 ) 1.3 ) 14.1 ) -3.9 ) 2.4
2 3 250 47 19 /// 9.0 12.2 5.7 20.3 -0.4 1.9
3 4 205 59 12 /// 15.3 19.1 ) 10.7 ) 27.7 ) 3.9 ) 2.3
4 5 154 64 20 /// 18.4 22.7 14.2 28.2 9.6 1.8
5 6 216 77 13 /// 21.5 25.4 ) 17.8 ) 29.2 ) 13.9 ) 1.8
6 7 280 125 20 /// 25.6 28.8 22.8 33.6 17.8 2.6
7 8 192 110 30 /// 27.2 30.7 24.2 35.1 20.9 2.1
8 9 212 60 32 /// 24.0 27.4 21.3 31.8 15.6 1.9
9 10 88 22 7 /// 17.8 21.7 13.9 26.9 7.1 1.5
10 11 37 23 5 /// 11.3 15.4 7.4 20.1 1.9 2.1
11 12 45 13 5 /// 6.4 9.2 ) 3.0 ) 16.1 ) -1.7 ) 2.6
日照時間(h) 雪(cm)
最大風速 最大瞬間風速 日照時間(h) 降雪の合計 日降雪の最大 最深積雪
風速 風向 風速 風向 日照時間(h) 降雪の合計 日降雪の最大 最深積雪
0 6 西北西 /// /// 146.6 /// /// ///
1 9 西北西 /// /// 152.5 /// /// ///
2 7 西 /// /// 150.7 /// /// ///
3 8 西南西 /// /// 186.4 /// /// ///
4 8 南南西 /// /// 246.1 /// /// ///
5 9 南東 /// /// 220.4 /// /// ///
6 7 南南西 /// /// 220.8 /// /// ///
7 7 南南西 /// /// 275.3 /// /// ///
8 7 北 /// /// 185.5 /// /// ///
9 5 南南西 /// /// 205.6 /// /// ///
10 7 西北西 /// /// 188.1 /// /// ///
11 7 西北西 /// /// 160.5 /// /// ///
2番目の中身。
print(table[1])
0 1 2 3
0 利用される方へ よくある質問(FAQ) 気象観測統計の解説 年・季節・各月の天候
ということで、1番目の中身が欲しいテーブルだ。そこで、リストの1番目から中身を取りだして、typeを確かめて見れば、pandasのDataFrameになっていることがわかる。
df=table[0]
print(type(df))
<class 'pandas.core.frame.DataFrame'>
コラムの内容を見てみる。
df.columns
MultiIndex([( '月', '月', '月'),
( '降水量(mm)', '合計', '合計'),
( '降水量(mm)', '日最大', '日最大'),
( '降水量(mm)', '最大', '1時間'),
( '降水量(mm)', '最大', '10分間'),
( '気温(℃)', '平均', '日平均'),
( '気温(℃)', '平均', '日最高'),
( '気温(℃)', '平均', '日最低'),
( '気温(℃)', '最高', '最高'),
( '気温(℃)', '最低', '最低'),
('風向・風速(m/s)', '平均風速', '平均風速'),
('風向・風速(m/s)', '最大風速', '風速'),
('風向・風速(m/s)', '最大風速', '風向'),
('風向・風速(m/s)', '最大瞬間風速', '風速'),
('風向・風速(m/s)', '最大瞬間風速', '風向'),
( '日照時間(h)', '日照時間(h)', '日照時間(h)'),
( '雪(cm)', '降雪の合計', '降雪の合計'),
( '雪(cm)', '日降雪の最大', '日降雪の最大'),
( '雪(cm)', '最深積雪', '最深積雪')],
)
マルチインデックスのコラム名になってややこしいようであるが、ようはつなげていけば、細目に降りていく。
df["降水量(mm)"]
合計 | 日最大 | 最大 | ||
---|---|---|---|---|
合計 | 日最大 | 1時間 | 10分間 | |
0 | 65 | 22 | 9 | /// |
1 | 84 | 22 | 10 | /// |
2 | 250 | 47 | 19 | /// |
3 | 205 | 59 | 12 | /// |
4 | 154 | 64 | 20 | /// |
5 | 216 | 77 | 13 | /// |
6 | 280 | 125 | 20 | /// |
7 | 192 | 110 | 30 | /// |
8 | 212 | 60 | 32 | /// |
9 | 88 | 22 | 7 | /// |
10 | 37 | 23 | 5 | /// |
11 | 45 | 13 | 5 | /// |
df["降水量(mm)"]["合計"]
合計 | |
---|---|
0 | 65 |
1 | 84 |
2 | 250 |
3 | 205 |
4 | 154 |
5 | 216 |
6 | 280 |
7 | 192 |
8 | 212 |
9 | 88 |
10 | 37 |
11 | 45 |
df["降水量(mm)"]["合計"]["合計"]
0 65
1 84
2 250
3 205
4 154
5 216
6 280
7 192
8 212
9 88
10 37
11 45
Name: 合計, dtype: int64
最後の出力のtypeを確認すると、pandasのSeries形式になっている。
type(df["降水量(mm)"]["合計"]["合計"])
pandas.core.series.Series
後は、インデックスを日付形式にしたり、年でforループを回して連結したり、他の地点に変えたりと、いかようにも扱えるはず。