まだまだ、コロナが収まる気配は有りませんねー

東京都の感染者のデータを見てみましょう。

解説動画はこちら

 
まずはライブラリとデータの読み込みです。

このコードでオンラインからデータを
引っ張ってくることができます。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.simplefilter('ignore')

%matplotlib inline

url = 'https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv'
# データ読み込み
df = pd.read_csv(url)

これでデータフレームにデータが取り込まれました。

データを見てみましょう。
# 先頭行
df.head(3)
# 末尾
df.tail(3)

データ量やカラムの確認も行いましょう。
# データ量
df.shape
(15107, 16)
# カラム名
df.columns
Index(['No', '全国地方公共団体コード', '都道府県名', '市区町村名', '公表_年月日', '曜日', '発症_年月日', '患者_居住地', '患者_年代', '患者_性別', '患者_属性', '患者_状態', '患者_症状', '患者_渡航歴の有無フラグ', '備考', '退院済フラグ'], dtype='object')

今日現在は2020/8/8ですが
8/7までのデータがあるようです。

使えそうなデータを見てみると
年代や、日付などが使えそうです。

年代別で集計してみましょう。
# カテゴリ別で集計
df['患者_年代'].value_counts()
20代 5169
30代 3297
40代 2041
50代 1554
60代 947
70代 768
80代 489
10代 369
10歳未満 232
90代 227
100歳以上 6
不明 6
- 2
Name: 患者_年代, dtype: int64

データ上では少し不備があり
不明なども見受けられますね。

少しだけみやすくまとめてみます。
# 年代をまとめる
df['age'] = (
    df['患者_年代'].replace(['10歳未満', '10代'], '0-19')
    .replace(['20代', '30代'], '20-39')
    .replace(['40代', '50代'], '40-59')
    .replace(['60代', '70代'], '60-79')
    .replace(['80代', '90代'], '80-99')
    .replace(['100歳以上'], '100-')
    .replace(['不明', "'-",'-'], '不明')
)

# 結果
df['age'].value_counts()
20-39    8466
40-59    3595
60-79    1715
80-99     716
0-19      601
不明          8
100-        6
Name: age, dtype: int64

感染者の多くは20,30代のようですね。

日別でも見ていきましょう。
日別でのデータ操作を行うには
日の部分の文字列を
data型に直してあげる必要があります。
# 日付をdatatime型にしてカラム追加
df['date'] = pd.to_datetime(df['公表_年月日'])

# 結果
df['date'].head()
0   2020-01-24
1   2020-01-25
2   2020-01-30
3   2020-02-13
4   2020-02-14
Name: date, dtype: datetime64[ns]

これで準備ができたので
日別での集計をしてみましょう。
# 年代別日別の感染者数集計を行う
date_df = pd.crosstab(df['date'], df['age'])

# 週別で集計し直す
day_df = date_df.resample('D', label='left').sum()
day_df.index = day_df.index.strftime('%Y-%m-%d')

# 結果
day_df.head()

# 棒グラフで描画する
day_df.plot(kind='bar',stacked=True,figsize=(12, 6))
plt.show()
download


これだとデータが細かすぎて
わけわからないですね。

週別でまとめてみます。
# 年代別日別の感染者数集計を行う
date_df = pd.crosstab(df['date'], df['age'])

# 週別で集計し直す
week_df = date_df.resample('W', label='left').sum()
week_df.index = week_df.index.strftime('%Y-%m-%d')

# 結果
week_df.head()

# 棒グラフで描画する
week_df.plot(kind='bar',stacked=True,figsize=(12, 6))
plt.show()
download-1

割とみやすくなりましたね。

続いて割合で見てみましょう。

# 割合に直したデータフレームの作成
week_rate_df = (week_df.T / week_df.sum(axis=1)).T

# 棒グラフで描画
week_rate_df.plot(kind='bar',stacked=True,figsize=(12, 6))
plt.show()
download

最初は年齢が高めの方の感染が多かったようですが
現在の主流は2-30代のようです。



ついで前週比です。
# 前週比に直したデータフレームの作成
week_df_ratio = week_df / week_df.shift()

# 折れ線グラフで描画
week_df_ratio['2020-06-07':].plot(grid=True,figsize=(12, 4))
plt.show()

download-1



ヒートマップもみてみましょう。
# 年代をまとめたカラムを追加する
df['age2'] = df['患者_年代'].replace(
    {'10歳未満': '0-9', '10代': '10-19', '20代': '20-29', '30代': '30-39', 
     '40代': '40-49', '50代': '50-59', '60代': '60-69', '70代': '70-79', 
     '80代': '80-89', '90代': '90-', '100歳以上': '90-'}
)

# 日別、年代別でヒートマップ用のデータフレームを作成する
heat_df = pd.crosstab(df['公表_年月日'], df['age2']).T[::-1]
plt.figure(figsize=(15, 4))

# seabornでヒートマップを可視化する
sns.heatmap(heat_df, cmap='nipy_spectral')
plt.show()
download-2

20代の感染が濃いですね。
やはり活動が活発な年代ほど
接触しやすくなるのでしょうか?

続いて退院フラグがあるので
それをみてみましょう。
# 退院フラグを追加
df['flg'] = df['退院済フラグ'].fillna(0).astype('int')

# 日別、フラグ別で集計したデータフレームを作成
disch_df = pd.crosstab(df['date'], df['flg'])

# 週別でリサンプリング
disch_df2 = disch_df.resample('W', label='left').sum()
disch_df2.index = disch_df2.index.strftime('%Y-%m-%d')

# 棒グラフで可視化
disch_df2.plot(kind='bar',stacked=True,figsize=(16, 5))
plt.show()
download

これでみると、早ければ2週間ほどで
退院できているようです。

中には1ヶ月以上退院できていない人もいるようなので
長期の治療を要することを
念頭に置いておかないといけませんね。


最後に移動平均です。
# 日付のデータフレームを作成
mean_df = df['date'].value_counts().sort_index()
mean_df = mean_df[30:]
fig, ax = plt.subplots(figsize=(16, 5))

# 二軸でグラフ作成
ax.bar(mean_df.index, mean_df, width=1, color='silver', edgecolor='black')
ax.plot(mean_df.index, mean_df.rolling(7).mean(), color='blue')
plt.show()
download-1


移動平均でならしても
増加傾向にあるのが分かりますね。

まだまだ油断はできません。

まあ、自分はリモートワーカーなんで
ほぼ人には接触しませんので
自粛しまくり状態ではあります。

早くワクチンなどが
開発されることを願っております。