Ввиду того, что коронавирус всё же распространился по всему миру, я решил сопоставить данные по вирусу в сравнение с тем, что было в Китае. Когда пандемия только начиналась, я сделал небольшой анализ данных по Китаю, и так как там ситуация почти локализована, то интересно было бы посмотреть в какой стадии находятся другие страны, где пандемия начала сильно распространяться. Данный анализ ни на что не претендует и является субъективным мнением автора.



© Роспотребнадзор


1. Получение данных


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

sns.set(rc={'figure.figsize':(20, 5)})

В первом анализе данных я использовал данные напрямую из отчетов ВОЗ, но в этот раз удобнее было взять их из отчётов университета Джонса Хопкинса, которые находятся здесь.


confirmed = pd.read_csv('time_series_19-covid-Confirmed.csv')
recovered = pd.read_csv('time_series_19-covid-Recovered.csv')
deaths = pd.read_csv('time_series_19-covid-Deaths.csv')

# страны с самым большим количесвом заразившихся людей
df = confirmed.copy()
df = df.groupby('Country/Region').sum()
df = df.sort_values(by=df.columns[-1], ascending=False)

countries = list(df.head(5).index)

Из этих данных я получил страны в которых наибольшее число заразившихся людей и выбрал из них пять стран с наихудшей ситуацией включая Китай.


print(countries)

['China', 'Italy', 'Iran', 'Spain', 'Germany']

def transform_data(df, countries):
    df = df[df['Country/Region'].isin(countries)]
    columns = [i for i in df.columns if i not in ['Province/State', 'Lat', 'Long']]
    df = df[columns]    
    df = df.groupby('Country/Region').sum()

    df = df.T
    df['Date'] = df.index
    df['Date'] = pd.to_datetime(df['Date'], format='%m/%d/%y')
    df = df.reset_index(drop=True)
    df.columns.name = None

    def by_day(col):
        res = col.rolling(window=2).apply(lambda x: x.iloc[1] - x.iloc[0])
        res[0] = col[0]
        return res

    df[countries] = df[countries].apply(by_day)

    return df

Затем для каждой из пяти стран я расчитал количество заразившихся, умерших и выздоровевших за день.


confirmed = transform_data(confirmed, countries)
recovered = transform_data(recovered, countries)
deaths = transform_data(deaths, countries)

2. Чистка данных от выбросов


К сожалению данные о количестве выздоровевших совсем не подходят для анализа, т.к. сильно разобщены и совсем не имеют никакой динамики, по-этому я их не буду использовать.


Чистка выбросов для количества заразившихся людей заключается в том, что когда два дня подряд сильно выбиваются из общей картины, т.е. в одинь день подозрительно мало, в другой слишком много заразившихся, то я просто беру их среднее число. Однако по Китаю за числа 2020-02-12 — 2020-02-14 данные уж слишком сильно выбиваются из общей картины, по-этому за эти даты я взял данные из своего первого отчета, который я сделал на основе данных отчетов ВОЗ.


confirmed.loc[confirmed['Date'].isin(['2020-02-22', '2020-02-23']), 'China'] = confirmed.loc[confirmed['Date'].isin(['2020-02-22', '2020-02-23']), 'China'].mean()

#2020-02-12 - 2020-02-14 Данные из отчётов ВОЗ
confirmed.loc[confirmed['Date'] == '2020-02-12', 'China'] = 2022
confirmed.loc[confirmed['Date'] == '2020-02-13', 'China'] = 1820
confirmed.loc[confirmed['Date'] == '2020-02-14', 'China'] = 1998

confirmed.loc[confirmed['Date'].isin(['2020-03-12', '2020-03-13']), 'Italy'] = confirmed.loc[confirmed['Date'].isin(['2020-03-12', '2020-03-13']), 'Italy'].mean()

confirmed.loc[confirmed['Date'].isin(['2020-03-12', '2020-03-13']), 'Spain'] = confirmed.loc[confirmed['Date'].isin(['2020-03-12', '2020-03-13']), 'Spain'].mean()

В данных по количеству умерших я почистил данные аналгоично, т.е. если в данных были два подряд идущие дня выбивающиеся из общей динамики, то я брал их среднее.


deaths.loc[deaths['Date'].isin(['2020-01-28', '2020-01-29']), 'China'] = deaths.loc[deaths['Date'].isin(['2020-01-28', '2020-01-29']), 'China'].mean()
deaths.loc[deaths['Date'].isin(['2020-02-12', '2020-02-13']), 'China'] = deaths.loc[deaths['Date'].isin(['2020-02-12', '2020-02-13']), 'China'].mean()
deaths.loc[deaths['Date'].isin(['2020-02-21', '2020-02-22']), 'China'] = deaths.loc[deaths['Date'].isin(['2020-02-21', '2020-02-22']), 'China'].mean()
deaths.loc[deaths['Date'].isin(['2020-02-23', '2020-02-24']), 'China'] = deaths.loc[deaths['Date'].isin(['2020-02-23', '2020-02-24']), 'China'].mean()

deaths.loc[deaths['Date'].isin(['2020-03-12', '2020-03-13']), 'Italy'] = deaths.loc[deaths['Date'].isin(['2020-03-12', '2020-03-13']), 'Italy'].mean()

3. Отрисовка графиков


def draw_graph(deaths, confirmed, country):
    fig, ax = plt.subplots()
    plt.xticks(rotation=45, ha="right")
    sns.lineplot(x='Date', y=country, data=deaths, ax=ax, color='b', label='Умершие', marker='o')
    ax.set(xlabel='Дата', ylabel='Кол-во умерших за день')
    plt.legend(bbox_to_anchor=(0.01, 0.95), loc='upper left')
    ax2 = ax.twinx()
    sns.lineplot(x='Date', y=country, data=confirmed, ax=ax2, color='r', label='Инфицированные', marker='o')
    ax2.set(ylabel='Кол-во инфицированных за день');
    plt.legend(bbox_to_anchor=(0.01, 0.85), loc='upper left');

    ax.set(xticks=confirmed['Date'].values);

Как и в первом отчете, я наложил графики количества заразившихся и количества умерших за день друг на друга.


Китай:


draw_graph(deaths, confirmed, 'China')


На графике по Китаю видно смещение пиков, которое объясняется инкубационным периодом вируса (что было верно подмечено здесь пользователем Andy_U в комментариях по первому анализу), именно с таким развитием событий я и пытаюсь сравнить данные по другим странам.


Италия:


draw_graph(deaths, confirmed, 'Italy')


Иран:


draw_graph(deaths, confirmed, 'Iran')


Возможно в Иране намечается разворот?, по крайней мере на это похоже.


Испания:


draw_graph(deaths, confirmed, 'Spain')


Германия:


draw_graph(deaths, confirmed, 'Germany')


4. Выводы


Из графиков видно, что пандемия только набирает обороты, хотя возможно, намечается разворот в данных по Ирану. Повторю опять, что я пытаюсь сравнить графики того, что было в Китае с тем, что сейчас происходит в других странах и похоже прогноз пока негативный.


Исходный код.


Первый пост по коронавирусу — "Анализ данных по коронавирусу SARS-CoV-2 (2019-nCov)", прочитать можно здесь.