EDA по набору данных о коронавирусе Университета Джона Хопкинса.

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

Всемирная организация здравоохранения (ВОЗ) объявила вспышку коронавируса в Ухане чрезвычайной ситуацией в области общественного здравоохранения, имеющей международное значение.

В этой статье мы кратко рассмотрим текущий кризис, а затем углубимся в Новый набор данных о вирусе короны 2019 от Kaggle. Я также создал репозиторий GitHub для всех, кто хотел бы воссоздать шаги и добавить свои собственные идеи.

Что такое коронавирус?

По данным ВОЗ, коронавирусы (CoV) - это большое семейство вирусов, которые вызывают заболевания, начиная от простуды и заканчивая более тяжелыми заболеваниями, такими как ближневосточный респираторный синдром (MERS-CoV) и тяжелый острый респираторный синдром (SARS-CoV).

Новый коронавирус (nCoV) - это новый штамм, который ранее не обнаруживался у людей. Вирус, идентифицированный как причина недавней вспышки, упоминается как 2019-nCoV или уханьский коронавирус.

Кризис на сегодняшний день

Согласно последнему отчету New York Times, число подтвержденных инфекций выросло до 37 198 и число погибших в Китае возросло до 811, что превышает число погибших от Эпидемия атипичной пневмонии.

Шестнадцать городов Китая с общим населением более 50 миллионов человек находятся в изоляции. Авиакомпании по всему миру отменили рейсы в Китай и из Китая. Некоторые страны эвакуируют своих граждан специальными рейсами и в дальнейшем помещают их на строгий карантин.

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

Введение в набор данных

Набор данных о новом коронавирусе 2019, опубликованный на Kaggle, был собран Университетом Джона Хопкинса. Команда собрала данные из различных источников, таких как ВОЗ, местные Центры контроля заболеваний и СМИ. Они также создали приборную панель в реальном времени для отслеживания распространения вируса.

Заявление об ограничении ответственности: обратите внимание, что набор данных не обновляется, поэтому наблюдения, записанные ниже, могут не соответствовать текущему сценарию.

Импорт библиотек и загрузка данных

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
#reading data from the csv file
data= pd.read_csv("/kaggle/input/novel-corona-virus-2019-dataset/2019_nCoV_data.csv")

Понимание набора данных

Давайте сначала получим общее представление о наборе данных и при необходимости выполним операции очистки данных.

#checking the number of rows and columns
data.shape

Вывод: (770, 8). В наборе данных 770 наблюдений и 8 столбцов.

#checking the top 5 rows
data.head()

Имена столбцов говорят сами за себя. Первый столбец «Sno» выглядит как номер строки и не добавляет никакой ценности анализу. Пятый столбец «Последнее обновление» показывает то же значение, что и столбец «Дата», за исключением нескольких случаев, когда числа были обновлены позже. Прежде чем продолжить, удалим эти два столбца.

#dropping the 1st and 5th column
data.drop("Sno", axis=1, inplace=True)
data.drop("Last Update", axis=1, inplace=True)
#getting a summary of the columns
data.info()

За исключением «Область / Штат», ни один из столбцов не имеет нулевых значений. Дальнейший анализ показывает, что названия провинций отсутствуют для таких стран, как Великобритания, Франция и Индия. В этом случае мы не можем принять или заполнить отсутствующие значения из какого-либо главного списка. Перейдем к числовым столбцам.

data.describe()

Метод describe() возвращает общую статистику числовых столбцов в фрейме данных.

Непосредственный вывод из выходных данных состоит в том, что данные были сообщены кумулятивно, то есть количество случаев, зарегистрированных в любой конкретный день, включает случаи, о которых сообщалось ранее. «Максимальное» значение смертей составляет 479, что согласуется с сообщениями СМИ несколько дней назад (когда были опубликованы эти данные).

#checking for duplicate rows
duplicate_rows=data.duplicated(['Country','Province/State','Date'])
data[duplicate_rows]

Метод duplicated() возвращает логический ряд, который затем используется в качестве маски в исходном фрейме данных. Выходные данные показывают, что нет двух записей с одинаковой страной, штатом и датой. Таким образом, мы можем сделать вывод, что все наблюдения в наборе данных уникальны.

#listing all the countries where the virus has spread to
country_list=list(data['Country'].unique())
print(country_list)
print(len(country_list))

Данные показывают, что вирус распространился в 32 страны Азии, Европы и Америки. Для целей этого анализа мы можем объединить данные по «Китаю» и «материковому Китаю».

#merging China and Mainland China
data.loc[data['Country']=='Mainland China','Country']='China'

Прежде чем двигаться дальше, давайте проверим даты в столбце «Дата».

print(list(data['Date'].unique()))
print(len(list(data['Date'].unique())))

Похоже, что данные обновлялись каждый день в разное время. Мы можем извлечь даты из метки времени и использовать их для дальнейшего анализа. Это поможет нам сохранить единообразие дат.

#converting 'Date' column to datetime object
data['Date'] = pd.to_datetime(data['Date'])
#extracting dates from timestamps
data['Date_date']=data['Date'].apply(lambda x:x.date())

Давайте разберемся с последствиями эпидемии для каждой страны.

#getting the total number of confirmed cases for each country
df_country=data.groupby(['Country']).max().reset_index(drop=None)
print(df_country[['Country','Confirmed','Deaths','Recovered']])

Поскольку данные являются кумулятивными, нам необходимо использовать функцию max() с groupby() , чтобы получить максимальное количество зарегистрированных случаев для каждой страны. Если мы используем sum(), мы будем вести двойной учет.

Данные подтверждают, что на данный момент в Китае зарегистрировано наибольшее количество случаев заболевания и почти все из 481 случая смерти. Что более позитивно, Китай также имеет 522 выздоровления, за ним следует Таиланд, у которого 7.

#preparing data for a time-series analysis
df_by_date=data.groupby(['Date_date']).sum().reset_index(drop=None)
df_by_date['daily_cases']=df_by_date.Confirmed.diff()
df_by_date['daily_deaths']=df_by_date.Deaths.diff()
df_by_date['daily_recoveries']=df_by_date.Recovered.diff()
print(df_by_date)

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

Построение данных

Для визуализации данных мы будем использовать две мощные библиотеки Python - Matplotlib и Seaborn. Matplotlib - это библиотека 2D-визуализации по умолчанию, используемая большинством специалистов по данным. Seaborn, построенный на основе matplotlib, помогает создавать более привлекательные и сложные визуализации, такие как тепловые карты.

Давайте создадим пять визуализаций на основе разных аспектов данных.

  1. Количество подтвержденных случаев за определенный период
#plotting a bar chart of confirmed cases over time
sns.axes_style("whitegrid")
sns.barplot(
x="Date_date", 
y="Confirmed", data=data.groupby(['Date_date']).sum().reset_index(drop=None)
)
plt.xticks(rotation=60)
plt.ylabel('Number of confirmed cases',fontsize=15)
plt.xlabel('Dates',fontsize=15)

2. Уровень смертности и скорость выздоровления

#plotting two line plots for deaths and recoveries respectively
plt.plot('date_updated', 'Deaths', data=data.groupby(['date_updated']).sum().reset_index(drop=None), color='red')
plt.plot('date_updated', 'Recovered', data=data.groupby(['date_updated']).sum().reset_index(drop=None), color='green')
plt.xticks(rotation=60)
plt.ylabel('Number of cases',fontsize=15)
plt.xlabel('Dates',fontsize=15)
plt.legend()
plt.show()

3. 10 наиболее пострадавших стран, помимо Китая

#We know that China is the most affected country by a large margin, #so lets create a bar plot to compare countries other than China
#increasing the figure size
plt.rcParams['figure.figsize']=(15,7)
sns.barplot(
x="Country",
y="Confirmed",
data=df_country[df_country.Country!='China'].nlargest(10,'Confirmed'),
palette=sns.cubehelix_palette(15, reverse=True)
)
plt.ylabel('Number of cases',fontsize=15)
plt.xlabel('Countries',fontsize=15)
plt.xticks(fontsize=13)
plt.yticks(fontsize=13)

4. Коэффициент смертности с течением времени

#The mortality rate, at any point in time, can be roughly calculated #by dividing the number of deaths by the number of confirmed cases
df_by_date['mrate']=df_by_date.apply(lambda x: x['Deaths']*100/(x['Confirmed']), axis=1)
plt.plot('Date_date','mrate',data=df_by_date, color='red')
plt.show()

5. Подробнее о 10 наиболее пострадавших провинциях Китая

#creating a separate dataframe for provinces
df_province=data[data['Country']=='China'].groupby(['Province/State']).max().reset_index(drop=None)
#selecting 10 most affected provinces
df_province=df_province.nlargest(10,'Confirmed')
df_province=df_province[['Province/State','Deaths','Recovered']]
#for multi-bar plots in seaborn, we need to melt the dataframe so #that the the deaths and recovered values are in the same column
df_province= df_province.melt(id_vars=['Province/State'])

sns.barplot(
x='Province/State', 
y='value', 
hue='variable', 
data=df_province
)
plt.xlabel('Provinces',fontsize=15)
plt.ylabel('Number of cases',fontsize=15)

Наблюдения

  1. Количество случаев, регистрируемых ежедневно, с 28 января увеличилось почти на 250%. 4 февраля было зарегистрировано 3915 случаев заболевания. Это показывает, что вирус очень заразен и быстро распространяется.
  2. В течение первой недели количество смертей было больше, чем выздоровление. С 31 января темпы восстановления резко выросли и демонстрируют положительную динамику. 4 февраля было 255 случаев выздоровления по сравнению с 66 смертельными случаями. Скорость выздоровления будет продолжать расти по мере того, как все больше людей узнают о симптомах и быстро обращаются за лекарствами.
  3. Страны, географически близкие к Китаю, такие как Таиланд, Япония и Сингапур, сообщили о большем количестве случаев заболевания, чем другие азиатские и европейские страны. Германия является исключением и имеет самое большое количество случаев в Европе.
  4. Смертность никогда не превышала 3% и постепенно снижается до 2%. Дальнейшее восстановление в ближайшие недели может еще больше снизить этот показатель.
  5. Китайская провинция Хубэй - эпицентр вспышки. В нем зарегистрировано значительно больше случаев заболевания, чем во всех других провинциях вместе взятых. В некоторых провинциях не было смертей и все больные выздоровели.

Заключение

Анализ показывает тревожные темпы распространения уханьского коронавируса. По крайней мере, 811 человек умерли во время нынешней эпидемии, что превышает 774 зарегистрированных смертельных случая во время вспышки атипичной пневмонии семь лет назад. Я молюсь и надеюсь, что вирус будет как можно скорее локализован.

Примечание редакции: todatascience.com - это издание Medium, в основном основанное на изучении науки о данных и машинного обучения. Мы не профессионалы в области здравоохранения и не эпидемиологи. Чтобы узнать больше о пандемии коронавируса, нажмите здесь.