今年の夏熱くない?
いつも私はエアコンなし・扇風機一本で夏を乗り切る男なのですが、
今年は暑さに耐え切れずエアコンを使用しています。
今年の夏の暑さが異常なのか、年を取って体力が落ちたのか、調査をしたいと思います。
調査方法
7月から8月までの平均気温と平均湿度を年ごとに折れ線グラフでプロットします。
データは気象庁のデータをスクレイピングすることで取得します。
モジュールインポート
import datetime
# データ分析
import pandas as pd
import numpy as np
# スクレイピング
import requests
from bs4 import BeautifulSoup
# 可視化
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
分析用dataframeの作成
分析対象日のdatetimeindexを作成する
index = pd.date_range(start="2022-07-01", end="2022-08-31")
for i in range(2):
# 一年分ずらす
y_delta = index - pd.DateOffset(years=1)
index = index.union(y_delta)
index
結果
indexの結合にはunionメソッドを使うらしい。また新しいものに対して古いものを結合したのに、
結合後は自動的に時系列に並び変えてくれた。すごい。
作成したindexを基にdataframeを作成する
df = pd.DataFrame(index=index)
df["temp."] = np.nan
df["hum"] = np.nan
df
結果
気象庁のデータをスクレイピングする
スクレイピング元
以下のようなページからデータを取得する。
年と月を基準にurlを更新すれば、その年月について日毎のデータが表に表示される。
年と月を基準にグループ化する
後述のスクレイピングのループのiteratorとするために、
年月単位でグルーピングしたindexを取得する。
mean処理は特に意味はないが、何らかの処理を行わないとdataframeになってくれないので、やむを得ず実行。
hoge = df.groupby(by=[df.index.year, df.index.month]).mean()
hoge.index
結果
気象庁のデータをスクレイピングする
url更新→テーブルデータ取得→所望の行と列からデータを抜いてdfに格納
for Y, m in hoge.index:
# urlを更新
url = f"https://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=44&block_no=47662&year={Y}&month={m}&day=&view="
# htmlのtable要素を取得
r = requests.get(url)
soup = BeautifulSoup(r.text)
table = soup.find("table", { "class" : "data2_s" })
#
for iter, tr in enumerate(table.findAll("tr")):
# 最初の四行は処理を行わない
if iter <= 3:
continue
# 1列目と7列目と10列目の値を取得
tds = tr.findAll("td")
d = int(tds[0].string)
try:
_temp = float(tds[6].string)
hum = float(tds[9].string)
except:
_temp, hum = [np.nan, np.nan]
# dfに格納
df.loc[pd.to_datetime(datetime.datetime(Y, m, d)), "temp.":"hum"] = [_temp, hum]
df
結果
データを可視化する
分析用の列を追加。
seabornで可視化を行う。
今回は月日毎の温度と気温の変化を年ごとに比べたいので、以下の様に列を追加。
df["m/d"] = [timestamp.strftime(r"%m/%d") for timestamp in df.index]
df["Y"] = df.index.year
df
結果
グラフで可視化
平均気温について
sns.set_style("whitegrid")
# figure定義
fig, ax = plt.subplots(figsize=(12.8, 7.2), dpi=100)
# plot
sns.lineplot(data=df, x="m/d", y="temp.", hue="Y")
# x軸を30度回転
fig.autofmt_xdate()
# x軸の表示間隔を5個ごとに変更
ax.xaxis.set_major_locator(ticker.MultipleLocator(5))
結果
全体的に今年の気温は例年よりも高い。
湿度について
fig, ax = plt.subplots(figsize=(12.8, 7.2), dpi=100)
sns.lineplot(data=df, x="m/d", y="hum", hue="Y")
fig.autofmt_xdate()
ax.xaxis.set_major_locator(ticker.MultipleLocator(5))
結果
意外なことに湿度は例年よりも低い時が多い。
まとめ
湿度についてはともかく、温度については例年よりも高いことが分かりました。
夏バテの影響は加齢のせいだけでないことがわかり安心しました。
また、pandasのtimestampやdatetimeについて、
少し理解が深まりまったこともよかったなと思います。
参考