Skip to content

Instantly share code, notes, and snippets.

@tirinox tirinox/corona.csv
Last active Jan 31, 2020

Embed
What would you like to do?
Предсказание числа заболевших коронавирусом из Китая
day infected dead
20.01.2020 278 4
21.01.2020 326 6
22.01.2020 547 8
23.01.2020 639 14
24.01.2020 916 25
25.01.2020 2000 40
26.01.2020 2700 57
27.01.2020 4400 64
28.01.2020 5970 87
29.01.2020 7818 170
30.01.2020 9700 213
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
from datetime import timedelta
from prettytable import PrettyTable
# загрузка данных
df = pd.read_csv('corona.csv', parse_dates=['day'])
print(df.head())
# экспоненциальная функция с параметрами
def fit_func_exp(x, a, b, c):
return a * np.exp(c * x) + b
# зависимая переменная y - ее будем предсказывать
train_infected = df['infected']
train_dead = df['dead']
# дни - преобразуем их в целые числа от 0 до максимального
days = range(len(df['day']))
# у нас 3 параметра в функции a, b, c – начальное приближение - единицы
p0 = np.ones(3)
# впишем кривую в наши данные
(a, b, c), _ = curve_fit(fit_func_exp, days, train_infected, p0=p0)
(a1, b1, c1), _ = curve_fit(fit_func_exp, days, train_dead, p0=p0)
# предскажем динамику вируса на 60 дней (начало соотвествует началу из данных 20 янв 2020)
MAX_DAY = 60
x_days = np.linspace(0, MAX_DAY - 1, MAX_DAY)
y_infect = fit_func_exp(x_days, a, b, c)
y_dead = fit_func_exp(x_days, a1, b1, c1)
# население Земли
EARTH_POPULATION = 7_530_000_000
# найдем номер дня, когда количество зараженных достигнет популяции Земли
doom_inf_index = np.argmax(y_infect >= EARTH_POPULATION)
doom_inf_day = x_days[doom_inf_index]
doom_dead_index = np.argmax(y_dead >= EARTH_POPULATION)
doom_dead_day = x_days[doom_dead_index]
# вычислим дату
day0 = df['day'][0]
doom_inf_date = day0 + timedelta(days=int(doom_inf_index))
doom_dead_date = day0 + timedelta(days=int(doom_dead_index))
# дата конца!
print(f'Дата заражение Земли: {doom_inf_date:%d.%m.%Y}')
print(f'Судный день: {doom_dead_date:%d.%m.%Y}')
# --- таблицу рисуем ---
table = PrettyTable()
table.field_names = ['Дата', 'Число заболевших', 'Число погибших']
cur_day = day0
for day, (inf_ppl, dead_ppl) in enumerate(zip(y_infect, y_dead)):
table.add_row([
f'{cur_day:%d.%m.%Y}',
int(inf_ppl),
int(dead_ppl)
])
cur_day += timedelta(days=1)
print(table)
# ----------------------
plt.xlabel('Дни')
plt.ylabel('Больные')
# в log шкале
plt.yscale('log')
# это данные текущей статистики - нарисуем их синими точками
plt.scatter(days, train_infected, marker='D', label='Реальные')
# это красная линия – предсказание
plt.plot(x_days[:22], y_infect[:22], 'r', label='Предсказание')
plt.legend()
plt.show()
# df.plot(kind='bar', x='day', y=['infected', 'dead'])
# plt.show()
@tirinox

This comment has been minimized.

Copy link
Owner Author

tirinox commented Jan 30, 2020

Результаты:
pred_plot

Doom date: 13.03.2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.