オープンデータで可視化した新型コロナワクチン接種状況
1年以上続くコロナ禍の出口への光となり得る新型コロナワクチン接種。
医療従事者に続き、65歳以上の一般接種が全国各地で始まっています。
政府CIOポータルでは、新型コロナワクチンの接種状況を可視化する目的で、ダッシュボードおよびオープンデータを提供されております。
ダッシュボードでは全国及び都道府県別の接種状況を簡単な操作で見ることができます。
このダッシュボードの元データになっているのが同じサイトで公開されているオープンデータ。
このオープンデータを使って、ダッシュボードにない視点で可視化、分析してみようというのが本記事での内容となります。
■オープンデータとは?
オープンデータとは,「機械判読に適したデータ形式で、二次利用が可能な利用ルールで公開されたデータ」であり「人手を多くかけずにデータの二次利用を可能とするもの」です。つまり,誰でも許可されたルールの範囲内で自由に複製・加工や頒布などができるデータをいいます。もちろん商用としても利用可能です。(引用:https://www.open-governmentdata.org/about/)
自治体オープンデータというサイトにわかりやすく書いてありましたので引用させてもらいましたが、太字のところに一言で集約されています。
■公開されている新型コロナワクチンの接種状況に関するオープンデータ
3種類あります。
①都道府県別接種回数詳細
②接種日別接種回数サマリー
③都道府県別累積接種回数サマリー
データの粒度としては①が一番細かく、
それを接種日別に接種回数を1回目、2回目ごとに集計したのが②、
都道府県別に最新の累積接種回数を1回目、2回目ごとに集計したのが③となります。
今回はデータの粒度が一番細かい①都道府県別接種回数詳細を使用して、可視化・分析を行っていきます。
■データを知る
まずは、都道府県別接種回数詳細データをダウンロードしてみましょう。
こちらの下の方にあるリンクからダウンロードできます。
ダウンロードしたファイルをメモ帳などのテキストエディタで開くと下記のように表示されます。
{"date":"2021-04-12","prefecture":"01","gender":"F","age":"-64","medical_worker":false,"status":1,"count":113}
{"date":"2021-04-12","prefecture":"01","gender":"F","age":"65-","medical_worker":false,"status":1,"count":88}
{"date":"2021-04-12","prefecture":"01","gender":"M","age":"-64","medical_worker":false,"status":1,"count":33}
{"date":"2021-04-12","prefecture":"01","gender":"M","age":"65-","medical_worker":false,"status":1,"count":25}
{"date":"2021-04-12","prefecture":"01","gender":"U","age":"-64","medical_worker":false,"status":1,"count":12}
{"date":"2021-04-12","prefecture":"01","gender":"U","age":"UNK","medical_worker":false,"status":1,"count":1}
これはJSON形式で書かれたデータで、{ }の中に"項目名:項目値"がカンマで区切られており、{}の中で1データとなっております。
このままだとちょっと見づらいので、Excelなどのスプレッドシートで読める形式に変換しておきます。
個々の項目の持つ意味合いについては下記に書かれています。
各項目について簡潔に説明すると以下のようになります。
date:接種日
prefecture:都道府県コード。北海道は01、東京都は13という風に全国地方公共団体コードというもので定められた値が入ります。
gender:性別。男性はM、女性はFですが、昨今のジェンダーレスを意識してか、U:不明という区分も設定されています
age:年代を表す区分値で64歳以下と65歳以上そして不明の3つの区分が設定されています。
medical_worker:医療従事者の接種か否かを表す項目でtrue、falseが入ります。現状はすべてfalseで、医療従事者の接種記録は含まれていませんが、今後入ってくる構想はあるのかもしれませんね。
status:該当の接種が1回目か2回目かを表す項目で1、2のいずれかが入ります。また、現在日本で承認されているワクチンにはありませんが、1回で接種が完了するワクチンの場合、接種時には2が入ります。
count:ここまでに上げた項目の組に該当するワクチンの接種回数が入ります。
例えば一番上の行は、
2021-04-12、北海道(都道府県コード01)の64歳以下、女性で1回目接種を行ったのが113人であることを表しています。
■全国の日ごとの接種状況をグラフ化する
可視化の一歩目として、トップ画像に示した全国の日ごとの接種状況をグラフ化してみようと思います。
ここからは随所にプログラミング言語が入ってきますが、わからない方は読み飛ばしていただいても文章としてはわかるようにしております。
▼1.オープンデータを読み込みtsv形式にして保存する
まずは、都道府県別接種回数詳細データをダウンロードし、後続の処理で使いやすいようタブ区切りのテキストファイルであるtsv形式で保存します。
# 政府CIOポータルから都道府県別接種回数詳細データをダウンロードする
data = urlopen(latest_data_url).read()
with open(input_data_path + tmp_filename, mode="wb") as f:
f.write(data)
# json形式のデータをDataFrameに読み込む
# Note:
# ndjson形式はjsonの値を改行で区切ったものであり、そのような形式のjsonデータを読み込む場合は
# orient='records', lines=True を指定することで読み込めるようになる。
df_data = pd.read_json(latest_data_url, orient='records', lines=True, encoding='utf-8')
# 暗黙的に意図しない型になってしまった項目を補正する
df_data[input_data_columns_en[1]] = df_data[input_data_columns_en[1]].map('{:02}'.format)
# オリジナルデータをtsv形式で保存
df_data.to_csv('org_data.tsv', sep='\t', index=False, encoding='utf-8')
▼2.日ごとの全国合計データを集計する
次に、日ごとの全国合計接種回数を集計して、そこからさらに1回目、2回目それぞれでの接種回数を集計していきます。
# オリジナルデータを読み込む
df_input = pd.read_csv('org_data.tsv', sep='\t', header=0, encoding='utf-8')
# 日ごとの総接種回数を集計し、カラム名を設定
df_output = pd.DataFrame(df_input[['date', 'count']].groupby(['date'], as_index=False).sum())
df_output.columns = ['接種日', '総接種回数']
# 日ごと、接種ステータス(1回目, 2回目)ごとの接種回数を集計し、カラム名を設定
# 1回目
df_tmp = df_input[df_input['status'].isin(['1'])] # 接種1回目のレコードを抽出
df_status_1 = pd.DataFrame(df_tmp[['date', 'count']].groupby(['date'], as_index=False).sum())
df_status_1.columns = ['接種日', '接種回数(1回目)']
# 2回目
df_tmp = df_input[df_input['status'].isin(['2'])] # 接種2回目のレコードを抽出
df_status_2 = pd.DataFrame(df_tmp[['date', 'count']].groupby(['date'], as_index=False).sum())
df_status_2.columns = ['接種日', '接種回数(2回目)']
df_output = pd.merge(df_output, df_status_1, on='接種日', how='left')
df_output = pd.merge(df_output, df_status_2, on='接種日', how='left')
# 全国合計の日ごとデータを保存
df_output.to_csv('graph_data.tsv', sep='\t', index=False, encoding='utf-8')
行っていることは難しくなくて、オープンデータで集計しているcountで示される値を、接種日単位で合計したのが総接種回数で、1回目、2回目の接種データに絞ってから合計したのが接種回数(1回目)、接種回数(2回目)となります。
▼3.7日間移動平均を算出する
日々の感染者数の報道でもキーワードとして出ていたのでご存じの方も多いかもしれませんが、一言で表すと、"直近7日間の平均値"となります。
日々の値だと、例えば平日と休日の差が激しい場合などに7日間移動平均を使うと、傾向が見えやすくなります。
# 各項目の7日間移動平均
df_output_7days_average = df_output.copy()
df_output_7days_average['7日間移動平均_総接種回数'] = df_output_7days_average['総接種回数'].rolling(7).mean().round(1)
df_output_7days_average['7日間移動平均_接種回数(1回目)'] = df_output_7days_average['接種回数(1回目)'].rolling(7).mean().round(1)
df_output_7days_average['7日間移動平均_接種回数(2回目)'] = df_output_7days_average['接種回数(2回目)'].rolling(7).mean().round(1)
df_output_7days_average = df_output_7days_average.drop(columns=['総接種回数', '接種回数(1回目)', '接種回数(2回目)'])
df_output_7days_average.columns = ['接種日', '総接種回数', '接種回数(1回目)', '接種回数(2回目)']
# 全国合計の日ごとデータ(7日間移動平均)を保存
df_output_7days_average.to_csv('graph_data_7avg.tsv', sep='\t', index=False, encoding='utf-8')
▼4.グラフを作成する
ここまで作成したデータを使ってグラフを作成します。
df_input = pd.read_csv('graph_data.tsv', sep='\t', header=0, encoding='utf-8')
df_input['接種日'] = pd.to_datetime(df_input['接種日'], format='%Y-%m-%d')
df_input_7avg = pd.read_csv('graph_data_7avg.tsv', sep='\t', header=0, encoding='utf-8')
df_input_7avg['接種日'] = pd.to_datetime(df_input_7avg['接種日'], format='%Y-%m-%d')
まずは作成したデータを読み込みます。
読み込んだ時点では接種日は単なる文字列としてしか認識されませんので、日付形式に変換しています。
fig, ax = plt.subplots(figsize=(20, 12))
# 積み上げ棒グラフ
ax.bar(df_input['接種日'], df_input['接種回数(1回目)'], color='green', label = '接種回数(1回目)')
ax.bar(df_input['接種日'], df_input['接種回数(2回目)'], color='pink', label = '接種回数(2回目)', bottom = df_input['接種回数(1回目)'])
ここからグラフを作成していきます。
まずは1回目と2回目の接種回数を積み上げて棒グラフとします。
ax.plot(df_input_7avg['接種日'], df_input_7avg['総接種回数'], color='black', label='7日間移動平均 総接種回数', lw=3)
ax.plot(df_input_7avg['接種日'], df_input_7avg['接種回数(1回目)'], color='red', label='7日間移動平均 接種回数(1回目)', lw=3)
ax.plot(df_input_7avg['接種日'], df_input_7avg['接種回数(2回目)'], color='blue', label='7日間移動平均 接種回数(2回目)', lw=3)
次に折れ線グラフで総接種回数、1回目、2回目の7日間移動平均を示します。
plt.xticks(df_input['接種日'], rotation=90)
plt.xlim(df_input['接種日'].min(), df_input['接種日'].max())
plt.ylim(0, 750000)
plt.xlabel('接種日')
plt.ylabel('接種回数')
plt.title('全国合計 新型コロナウィルスワクチン 総接種回数')
ax.xaxis.set_major_locator(mdates.DayLocator(bymonthday=None, interval=7, tz=None))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.legend()
plt.savefig('graph.png')
plt.close('all')
最後にグラフを成形して画像形式で保存します。
出来上がったグラフがトップ画像のものになります。
■グラフ化した全国の日ごとの接種状況を分析する
このグラフでわかることは、
・1日の総接種回数は増加の一途、最大で1日60万回を超えてきている
・7日間移動平均でも60万件に迫る勢いである
・7日間移動平均からは、1回目の接種がひと段落して、2回目の接種が進みつつある
逆にわからないことは、
・回数はわかった。俺が知りたいのは65歳以上の接種がどれぐらい進んでいるかだ!
・都道府県ごとの接種状況。どこが進んでいてどこが遅れているか
・希望者の接種が終わるのはいつ頃なの?
こんな感じかと思います。
長くなってきましたので本日はこの辺にしまして、次回は以下2点について可視化してみたいと思います。
・65歳以上の接種がどれぐらい進んでいるか
・都道府県ごとの接種状況
この記事が気に入ったらサポートをしてみませんか?