見出し画像

Pythonを使ってCOVID-19感染者データを加工してみる-part 2

4−2.スクリプトの詳細〜出力用リストの作成〜

上記のデータをもとに出力用に形を整えたリストを作成していきます。まず、グラフを書くときに面倒が生じないようにゼロ埋めを行います。今回使用させていただいているcsvファイルでは「ある日のある都道府県で感染者数がゼロ」のときのデータは存在しないので、日付データの点数と感染者数データの点数にずれが生じます。これをなくすために感染者数ゼロのときはゼロ埋めをするようにデータを加工して行きます。また同時に、別のページでお話しする予定の「10万人あたり感染者数」を計算するために各都道府県の人口データも格納していきます。そのための都道府県名と人口が羅列されたtxtファイルは別途用意してやる必要があります。こちらに参考までに私が作成したファイルをアップロードしておきますので、必要であればご使用ください。(スクリプトと同じフォルダに置いてください。)

txtデータを読み込みます。

txt_data_Pop = pd.read_table('./Region_Population_Data.txt', encoding="utf_8")
l_2d_Pop = txt_data_Pop.reset_index().values.tolist()
df_Pop = pd.DataFrame(l_2d_Pop, columns=['県名','RegionName','Population_10^5'])

l_regionというリストの中に、[都道府県名、人口]というリストを格納します。このとき、for文を用いてl_2d_regionというリストの中のデータを取り出していますが、ループさせる回数はリストに含まれる要素の数だけ行いたいので、len()でl_2d_regionの要素数を調べます。そして、for num in range()と書くことで()内の数字の回数だけ繰り返し処理が可能なので、ここへlen()で調べたリストの要素数を代入します。(numは任意の変数)

リストの要素全体を調べる際には有用なやり方だと思うので、私はこの方法をよく用いています。またリスト中にどんどん要素を追加していくためにはappend()を使用すればOKです。iatはpandasライブラリ中で使用するプロパティで、dataframeから指定した要素を抽出できます。

l_region = []
for n in range(len(l_2d_region)):
   col_Pop = df_Pop[df_Pop['RegionName'] ==  l_2d_region[n][1]]
   l_region.append([l_2d_region[n][1],col_Pop.iat[0,2]])

スクリーンショット 2020-11-28 23.17.24

ここから出力用のダミーリスト作成に入ります。まず日付はfrom_dで指定した日付から最新の日付まで一日ずつ日付を増やしながらループを回します。特定の日付のとき、l_regionに含まれる5つの都道府県ごとにリストが作成されるようにします。ここでは、一番内側のリストには[日付, 都道府県名, 0, 0]となるようにデータが格納してあり、次の工程でこのゼロの部分に対応した感染者数などを代入していきます。もし感染者数のような形でデータを抽出したい場合は、listの4項目、5項目にどんどん値を追加していくと良いと思います。最終的に出来上がるlst_allは下記のように三重の入れ子構造になっており少し複雑ですが、日付と都道府県名という2つの括りで整理してみると構造が理解しやすくなるかもしれません。

lst_all=[]
n_day = date_max - from_d
int_n_day = n_day.days + 1

for i in range(int_n_day):
   d = from_d + i * tdelta
   dstr = d.strftime('%-m/%-d/%Y')
   lst=[]
   j = 0
   for j in range(len(l_region)):
       lst.append([dstr,l_region[j][0],0])
   lst_all.append(lst)

スクリーンショット 2020-12-13 14.01.11

先程作成したダミーリストに前回計算した感染者数データを代入していきます。前回作成したl_2dという感染者数データが格納されたリストから、上位5つの都道府県名と一致する感染者数を抜き出します。抜き出した値は、先程作成したlst_allの3番目の項に代入されます。このときの処理も、日付の古い順から最新の日付までを順番に処理していきます。日付、都道府県名を調べ、対応する要素に感染者数を代入します。

ダミーリストを作って置くことでif文の処理に合うものは上で計算した感染者数が入力され、一方で処理から漏れたものに関しては、感染者数の値がゼロとなります。下記にlst_allの出力結果を示していますが、ここで大阪や北海道の感染者数がゼロなのはこのとき使用したデータで11/20までのデータがすべて揃っていないことが理由ですので、プログラム上の問題ではありません。

for i in range(int_n_day):
   d = from_d + i * tdelta
   dstr = d.strftime('%-m/%-d/%Y')
   for j in range(len(l_2d)):
       if l_2d[j][0] == dstr:
           for k in range(len(l_region)):
               if l_2d[j][1] == l_region[k][0]:
                   lst_all[i][k][2] = l_2d[j][2]

スクリーンショット 2020-12-13 14.00.17

4−3.スクリプトの詳細〜データの書き出し〜

データを書き出していきます。特に理由もないですが、カンマ区切りで書き出します。with open() as ...を用いて...に対応する名前のファイルを開きます。データ列の名前を最初に書き出すのですが、lst_all中に含まれないDateという名前だけ先にf.write()で書き込み、その後lst_allの1行目だけを読み込み、カンマをつけて書き出します。書き出す際は、リストの要素を文字列として扱いたいのでstr()で文字列に変換します。そして改行のため、"\n"とします。

lst_all中の感染者数を書き出す場合も同様にして順番にカンマをつけて書き出します。これで都道府県別の感染者数データ(上位5つの都道府県)が書き出せました。あとは書き出されたファイルをエクセルやグラフソフトで開いてグラフ化するだけです。出力したcsvファイルの中身を最後に示しておきます。

path_w = 'COVID_Infected_AtEachRegion.csv'

with open(path_w, mode='w') as f:
   f.write('Date')
   for l in range(len(lst_all[0])):
       f.write(',' + str(lst_all[0][l][1]))
   f.write("\n")


   for n in range(len(lst_all)):
       f.write(str(lst_all[n][0][0]))
       for m in range(len(lst_all[n])):
           f.write(',' + str(lst_all[n][m][2]))
       f.write("\n")

スクリーンショット 2020-12-13 14.20.57

スクリーンショット 2020-12-13 14.18.22

5.まとめと今後

スクリーンショット 2020-11-29 10.15.51

まずはこのような都道府県別の感染者数を示すグラフを作成するためのデータ加工を進めてきましたが、いかがでしたでしょうか。今回の目的はあくまでデータ加工をすることでしたので、ここでおしまいとなります。個人的な感想としては、データ加工の内容自体は大したことないので結構簡単かなと思ってやり始めてみたのですが、意外と勉強になることが多くて楽しかったです。次回は人口10万人あたりの感染者数がわかるようにデータ加工をしてみたいと思います。

この記事が気に入ったらサポートをしてみませんか?