Пример анализа данных на python: Коронавирус

392

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

Данные — Novel Corona Virus 2019 Dataset

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

import numpy as np # линейная алгебра
import pandas as pd # обработка данных, CSV afqk I/O (например pd.read_csv)
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_context('paper')
import random
def random_colours(number_of_colors):
    '''
    Простая функция для генерации случайных цветов.  
    Входные данные:  
	number_of_colors - целочисленное значение, указывающее
	 количество цветов, которые будут сгенерированы.  
    Выход:  
	Цвет в следующем формате: ['#E86DA4'].
    '''
    colors = []
    for i in range(number_of_colors):
        colors.append("#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)]))
    return colors

Статистический анализ

data = pd.read_csv('/novel-corona-virus-2019-dataset/2019_nCoV_data.csv')
data.head()
SnoProvince/StateCountryLast UpdateConfirmedDeathsRecovered
01AnhuiChina1/22/2020 12:001.00.00.0
12BeijingChina1/22/2020 12:0014.00.00.0
23ChongqingChina1/22/2020 12:006.00.00.0
34FujianChina1/22/2020 12:001.00.00.0
45GansuChina1/22/2020 12:000.00.00.0
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 497 entries, 0 to 496
Data columns (total 7 columns):
Sno               497 non-null int64
Province/State    393 non-null object
Country           497 non-null object
Last Update       497 non-null object
Confirmed         497 non-null float64
Deaths            497 non-null float64
Recovered         497 non-null float64
dtypes: float64(3), int64(1), object(3)
memory usage: 27.3+ KB

Растет метрик по числовым колонкам.

data.describe()
SnoConfirmedDeathsRecovered
count434.000000434.000000434.000000434.000000
mean217.50000080.7626731.8479261.525346
std125.429263424.70606815.3027929.038054
min1.0000000.0000000.0000000.000000
25%109.2500002.0000000.0000000.000000
50%217.5000007.0000000.0000000.000000
75%325.75000036.0000000.0000000.000000
max434.0000005806.000000204.000000116.000000

Растет метрик по не числовым колонкам.

data.describe(include="O")
Province/StateCountryLast Update
count393497497
unique453113
topNingxiaMainland China1/31/2020 19:00
freq1027463

Преобразуем данные Last Update в datetime

data['Last Update'] = pd.to_datetime(data['Last Update'])

Добавляем колонки Day и Hour

data['Day'] = data['Last Update'].apply(lambda x:x.day)
data['Hour'] = data['Last Update'].apply(lambda x:x.hour)

Данные только за 30 день января.

data[data['Day'] == 30]
SnoProvince/StateCountryLast UpdateConfirmedDeathsRecoveredDayHour
375376HubeiMainland China2020-01-30 21:30:005806.0204.0116.03021
376377ZhejiangMainland China2020-01-30 21:30:00537.00.09.03021
377378GuangdongMainland China2020-01-30 21:30:00393.00.011.03021
378379HenanMainland China2020-01-30 21:30:00352.02.03.03021
379380HunanMainland China2020-01-30 21:30:00332.00.02.03021
380381JiangxiMainland China2020-01-30 21:30:00240.00.07.03021
381382AnhuiMainland China2020-01-30 21:30:00237.00.03.03021
382383ChongqingMainland China2020-01-30 21:30:00206.00.01.03021
383384ShandongMainland China2020-01-30 21:30:00178.00.02.03021
384385SichuanMainland China2020-01-30 21:30:00177.01.01.03021
385386JiangsuMainland China2020-01-30 21:30:00168.00.02.03021
386387ShanghaiMainland China2020-01-30 21:30:00128.01.09.03021
387388BeijingMainland China2020-01-30 21:30:00121.01.05.03021
388389FujianMainland China2020-01-30 21:30:00101.00.00.03021
389390GuangxiMainland China2020-01-30 21:30:0087.00.02.03021
390391HebeiMainland China2020-01-30 21:30:0082.01.00.03021
391392YunnanMainland China2020-01-30 21:30:0076.00.00.03021
392393ShaanxiMainland China2020-01-30 21:30:0087.00.00.03021
393394HeilongjiangMainland China2020-01-30 21:30:0059.02.00.03021
394395HainanMainland China2020-01-30 21:30:0050.01.01.03021
395396LiaoningMainland China2020-01-30 21:30:0045.00.01.03021
396397ShanxiMainland China2020-01-30 21:30:0039.00.01.03021
397398TianjinMainland China2020-01-30 21:30:0032.00.00.03021
398399GansuMainland China2020-01-30 21:30:0029.00.00.03021
399400NingxiaMainland China2020-01-30 21:30:0021.00.01.03021
400401Inner MongoliaMainland China2020-01-30 21:30:0020.00.00.03021
401402XinjiangMainland China2020-01-30 21:30:0017.00.00.03021
402403GuizhouMainland China2020-01-30 21:30:0015.00.01.03021
403404JilinMainland China2020-01-30 21:30:0014.00.01.03021
404405Hong KongHong Kong2020-01-30 21:30:0012.00.00.03021
405406TaiwanTaiwan2020-01-30 21:30:009.00.00.03021
406407QinghaiMainland China2020-01-30 21:30:008.00.00.03021
407408MacauMacau2020-01-30 21:30:007.00.00.03021
408409TibetMainland China2020-01-30 21:30:001.00.00.03021
409410WashingtonUS2020-01-30 21:30:001.00.00.03021
410411IllinoisUS2020-01-30 21:30:002.00.00.03021
411412CaliforniaUS2020-01-30 21:30:002.00.00.03021
412413ArizonaUS2020-01-30 21:30:001.00.00.03021
413414NaNJapan2020-01-30 21:30:0011.00.01.03021
414415NaNThailand2020-01-30 21:30:0014.00.05.03021
415416NaNSouth Korea2020-01-30 21:30:006.00.00.03021
416417NaNSingapore2020-01-30 21:30:0010.00.00.03021
417418NaNVietnam2020-01-30 21:30:002.00.00.03021
418419NaNFrance2020-01-30 21:30:005.00.00.03021
419420NaNNepal2020-01-30 21:30:001.00.00.03021
420421NaNMalaysia2020-01-30 21:30:008.00.00.03021
421422OntarioCanada2020-01-30 21:30:002.00.00.03021
422423British ColumbiaCanada2020-01-30 21:30:001.00.00.03021
423424NaNCambodia2020-01-30 21:30:001.00.00.03021
424425NaNSri Lanka2020-01-30 21:30:001.00.00.03021
425426New South WalesAustralia2020-01-30 21:30:004.00.02.03021
426427VictoriaAustralia2020-01-30 21:30:002.00.00.03021
427428QueenslandAustralia2020-01-30 21:30:003.00.00.03021
428429BavariaGermany2020-01-30 21:30:004.00.00.03021
429430NaNFinland2020-01-30 21:30:001.00.00.03021
430431NaNUnited Arab Emirates2020-01-30 21:30:004.00.00.03021
431432NaNPhilippines2020-01-30 21:30:001.00.00.03021
432433NaNIndia2020-01-30 21:30:001.00.00.03021
433434NaNItaly2020-01-30 21:30:002.00.00.03021
data[data['Day'] == 30].sum()
Sno                                                      23895
Country      Mainland ChinaMainland ChinaMainland ChinaMain...
Confirmed                                                 9776
Deaths                                                     213
Recovered                                                  187
Day                                                       1770
Hour                                                      1239
dtype: object

Мы можем видеть, что число подтвержденных случаев для провинции Хубэй в Китае — 5806 на 30-е число. Количества смертей, выздоровевших и пострадавших, соответствует официальным на 30 января. Это означает, что в Confirmed уже включены люди, затронуте в предыдущие даты.

Создаем датасета с данными только за 30 января.

latest_data = data[data['Day'] == 30]
latest_data.head()
SnoProvince/StateCountryLast UpdateConfirmedDeathsRecoveredDayHour
375376HubeiMainland China2020-01-30 21:30:005806.0204.0116.03021
376377ZhejiangMainland China2020-01-30 21:30:00537.00.09.03021
377378GuangdongMainland China2020-01-30 21:30:00393.00.011.03021
378379HenanMainland China2020-01-30 21:30:00352.02.03.03021
379380HunanMainland China2020-01-30 21:30:00332.00.02.03021
print('Подтвержденные случаи (весь мир): ', latest_data['Confirmed'].sum())
print('Смерти (весь мир): ', latest_data['Deaths'].sum())
print('Выздоровления (весь мир): ', latest_data['Recovered'].sum())
Подтвержденные случаи (весь мир):  9776.0
Смерти (весь мир):  213.0
Выздоровления (весь мир):  187.0

Данные датасета соответствуют официальным данным.

Посмотрим как коронавирус распространялся с течением времени.

plt.figure(figsize=(16,6))
data.groupby('Day').sum()['Confirmed'].plot();

как коронавирус распространялся с течением времени

Со временем наблюдается экспоненциальный рост числа жертв короновируса.

plt.figure(figsize=(16,6))
sns.barplot(x='Day',y='Confirmed',data=data);

как коронавирус распространялся с течением времени

Глубокий разведочный анализ данных (EDA)

latest_data.groupby('Country').sum()
SnoConfirmedDeathsRecoveredDayHour
Country
Australia12819.00.02.09063
Cambodia4241.00.00.03021
Canada8453.00.00.06042
Finland4301.00.00.03021
France4195.00.00.03021
Germany4294.00.00.03021
Hong Kong40512.00.00.03021
India4331.00.00.03021
Italy4342.00.00.03021
Japan41411.00.01.03021
Macau4087.00.00.03021
Mainland China121269658.0213.0179.0930651
Malaysia4218.00.00.03021
Nepal4201.00.00.03021
Philippines4321.00.00.03021
Singapore41710.00.00.03021
South Korea4166.00.00.03021
Sri Lanka4251.00.00.03021
Taiwan4069.00.00.03021
Thailand41514.00.05.03021
US16466.00.00.012084
United Arab Emirates4314.00.00.03021
Vietnam4182.00.00.03021
  • Материковый Китай имеет ненулевые значения выздоровлений и смертей, которые можно изучить позже, создав отдельный набор данных

Провинции и регионы в которых нет зарегистрированных случаев заболевания.

data[data['Confirmed']==0]
SnoProvince/StateCountryLast UpdateConfirmedDeathsRecoveredDayHour
45GansuChina2020-01-22 12:00:000.00.00.02212
1011HeilongjiangChina2020-01-22 12:00:000.00.00.02212
1213Hong KongChina2020-01-22 12:00:000.00.00.02212
1516Inner MongoliaChina2020-01-22 12:00:000.00.00.02212
1819JilinChina2020-01-22 12:00:000.00.00.02212
2223QinghaiChina2020-01-22 12:00:000.00.00.02212
2324ShaanxiChina2020-01-22 12:00:000.00.00.02212
3031TibetChina2020-01-22 12:00:000.00.00.02212
3233XinjiangChina2020-01-22 12:00:000.00.00.02212
5354Inner MongoliaMainland China2020-01-23 12:00:000.00.00.02312
6061QinghaiMainland China2020-01-23 12:00:000.00.00.02312
6869TibetMainland China2020-01-23 12:00:000.00.00.02312
7778NaNPhilippines2020-01-23 12:00:000.00.00.02312
7879NaNMalaysia2020-01-23 12:00:000.00.00.02312
8081NaNAustralia2020-01-23 12:00:000.00.00.02312
8182NaNMexico2020-01-23 12:00:000.00.00.02312
8283NaNBrazil2020-01-23 12:00:000.00.00.02312
115116QinghaiMainland China2020-01-24 12:00:000.00.00.02412
263264NaNIvory Coast2020-01-27 20:30:000.00.00.02720
  • Интересно, что есть части материкового Китая, которые еще не были затронуты вирусом.
  • Есть страны без подтвержденных случаев заражения, и мы отбросим их.

Провинции и регионы в которых есть минимум 1 зарегистрированный случай заболевания.

data = data[data['Confirmed'] != 0]

Количество зараженных в разных странах.

plt.figure(figsize=(18,8))
sns.barplot(x='Country',y='Confirmed',data=data)
plt.tight_layout()

Количество зараженных в разных странах

  1. На графике показано то, что мы все знаем. Вирус больше всего затронул материковый Китай, однако есть сообщения о жертвах в соседних странах, что говорит о распространении вируса.
  2. Есть также случаи, подтвержденные в странах, которые далеко, таких как США, Таиланд, Япония и т. Д. Интересно, как вирус попал туда. Я предполагаю, что кто-то был в Ухане или близлежащем районе во время распространения вируса и увез его с собой домой, эта вспышка действительно опасна.

Количество зараженных в разных регионах.

import plotly.express as px
fig = px.bar(data, x='Province/State', y='Confirmed')
fig.show()

Количество зараженных в разных регионах

Анализ роста коронавируса в каждой стране

pivoted = pd.pivot_table(data, values='Confirmed', columns='Country', index='Day')
pivoted.plot(figsize=(16,10));

Анализ роста коронавируса в каждой стране

Визуализация вспышки в провинциях/регионах

pivoted = pd.pivot_table(data, values='Confirmed', columns='Province/State', index='Day')
pivoted.plot(figsize=(20,15));

Визуализация вспышки в провинциях

  • Hubei, наиболее пострадавшая провинция.
  • Также в подтвержденных случаях наблюдается тенденция к росту, и кажется, что состояние ухудшается.

Теперь давайте посмотрим на страны, которые были затронуты изначально, и страны, в которые сейчас проник коронный вирус.

data[data['Day'] == 22]['Country'].unique()
array(['China', 'US', 'Japan', 'Thailand', 'South Korea'], dtype=object)

Итак, в первый день, 22 января заражения были обнаружены в Китае, США, Японии, Таиланде

temp = data[data['Day'] == 22]
temp.groupby('Country').sum()['Confirmed'].plot.bar()

Заражения в первый день

Посмотрим на последние данные.

data[data['Day'] == 30]['Country'].unique()
array(['Mainland China', 'Hong Kong', 'Taiwan', 'Macau', 'US', 'Japan',
       'Thailand', 'South Korea', 'Singapore', 'Vietnam', 'France',
       'Nepal', 'Malaysia', 'Canada', 'Cambodia', 'Sri Lanka',
       'Australia', 'Germany', 'Finland', 'United Arab Emirates',
       'Philippines', 'India', 'Italy'], dtype=object)

Здесь мы видим, что вспышка распространилась в 23 странах к 30 января.

Рассмотрим только материковый Китай

data_main_china = latest_data[latest_data['Country']=='Mainland China']

Рассчитаем процент смертей.

(data_main_china['Deaths'].sum() / data_main_china['Confirmed'].sum())*100
2.205425553944916

Теперь процент выздоровлений.

(data_main_china['Recovered'].sum() / data_main_china['Confirmed'].sum())*100
1.8533857941602818
  • Мы можем видеть, что процент смертности от коронавируса — 2%, поэтому он не такой смертоносный, как другие вирусные вспышки.
  • Поскольку зарегистрировано мало случаев излечения, процент выздоровления составляет 1,87, это страшно. Хотя цифра может сильно вырасти, ведь 96% сейчас не попадают ни в одну из групп.

Трудоустройство после обучения

Где произошло большинство смертей

data_main_china.groupby('Province/State')['Deaths'].sum().reset_index(
	      ).sort_values(by=['Deaths'],ascending=False).head()
Province/StateDeaths
12Hubei204.0
10Heilongjiang2.0
11Henan2.0
9Hebei1.0
1Beijing1.0

Количество смертей по дням.

plt.figure(figsize=(16,6))
data.groupby('Day').sum()['Deaths'].plot();

График смертей в материковом Китае

График заболеваний в материковом Китае.

pivoted = pd.pivot_table(data[data['Country']=='Mainland China'] , values='Confirmed', columns='Province/State', index='Day')
pivoted.plot(figsize=(20,15))

График заболеваний в материковом Китае

pivoted = pd.pivot_table(data, values='Deaths', columns='Province/State', index='Day')
pivoted.plot(figsize=(20,15));

График смертей в материковом Китае по провинциям

Что дальше

Скачайте coronavirus.ipynb и данные по ссылке в начале статьи. Попробуйте построить свои графики и таблицы.

Тест на знание python

Что нужно вcтавить после "if", для вывода "x четное число"
Какой будет результат выполнения кода — print(+-1) ?
Какой будет результат выполнения этого кода?
Что делает код ниже?
Какой будет результат выполнения кода — print(abc) ?