4 "cell_type": "markdown",
9 "Data from [European Centre for Disease Prevention and Control](https://www.ecdc.europa.eu/en/publications-data/download-todays-data-geographic-distribution-covid-19-cases-worldwide)"
21 "import collections\n",
23 "import pandas as pd\n",
24 "import numpy as np\n",
25 "from scipy.stats import gmean\n",
28 "import matplotlib as mpl\n",
29 "import matplotlib.pyplot as plt\n",
41 "DEATH_COUNT_THRESHOLD = 10\n",
42 "COUNTRIES_CORE = 'IT DE UK ES IE FR BE'.split()\n",
43 "COUNTRIES_NORDIC = 'SE NO DK FI UK'.split()\n",
44 "COUNTRIES_FRIENDS = 'IT UK ES BE SI MX'.split()\n",
45 "# COUNTRIES_FRIENDS = 'IT UK ES BE SI PT'.split()\n",
47 "COUNTRIES_AMERICAS = ['AG', 'AR', 'AW', 'BS', 'BB', 'BZ', 'BM', 'BO', 'BR', 'VG', 'KY', # excluding Canada and USA\n",
48 " 'CL', 'CO', 'CR', 'CU', 'CW', 'DM', 'DO', 'EC', 'SV', 'GL', 'GD', 'GT',\n",
49 " 'GY', 'HT', 'HN', 'JM', 'MX', 'MS', 'NI', 'PA', 'PY', 'PE', 'PR', 'KN',\n",
50 " 'LC', 'VC', 'SX', 'SR', 'TT', 'TC', 'VI', 'UY', 'VE']\n",
51 "COUNTRIES_OF_INTEREST = list(set(COUNTRIES_CORE + COUNTRIES_FRIENDS))\n",
52 "COUNTRIES_ALL = list(set(COUNTRIES_CORE + COUNTRIES_FRIENDS + COUNTRIES_NORDIC + COUNTRIES_AMERICAS))"
57 "execution_count": 4843,
64 "output_type": "stream",
66 " % Total % Received % Xferd Average Speed Time Time Time Current\n",
67 " Dload Upload Total Spent Left Speed\n",
68 "100 553k 100 553k 0 0 564k 0 --:--:-- --:--:-- --:--:-- 564k\n"
73 "!curl https://opendata.ecdc.europa.eu/covid19/casedistribution/csv/ > covid.csv"
78 "execution_count": 4844,
84 "# First col is a date, treat geoId of NA as 'Namibia', not \"NA\" value\n",
85 "raw_data = pd.read_csv('covid.csv', \n",
86 " parse_dates=[0], dayfirst=True,\n",
87 " keep_default_na=False, na_values = [''],\n",
88 "# dtype = {'day': np.int64, \n",
89 "# 'month': np.int64, \n",
90 "# 'year': np.int64, \n",
91 "# 'cases': np.int64, \n",
92 "# 'deaths': np.int64, \n",
93 "# 'countriesAndTerritories': str, \n",
95 "# 'countryterritoryCode': str, \n",
96 "# 'popData2019': np.int64, \n",
97 "# 'continentExp': str, \n",
104 "execution_count": 4845,
115 "execution_count": 4845,
117 "output_type": "execute_result"
126 "execution_count": 4846,
132 "raw_data.fillna(0, inplace=True)"
137 "execution_count": 4847,
147 " .dataframe tbody tr th:only-of-type {\n",
148 " vertical-align: middle;\n",
151 " .dataframe tbody tr th {\n",
152 " vertical-align: top;\n",
155 " .dataframe thead th {\n",
156 " text-align: right;\n",
159 "<table border=\"1\" class=\"dataframe\">\n",
161 " <tr style=\"text-align: right;\">\n",
163 " <th>dateRep</th>\n",
164 " <th>year_week</th>\n",
165 " <th>cases_weekly</th>\n",
166 " <th>deaths_weekly</th>\n",
167 " <th>countriesAndTerritories</th>\n",
169 " <th>countryterritoryCode</th>\n",
170 " <th>popData2019</th>\n",
171 " <th>continentExp</th>\n",
172 " <th>notification_rate_per_100000_population_14-days</th>\n",
178 " <td>2020-12-14</td>\n",
179 " <td>2020-50</td>\n",
182 " <td>Afghanistan</td>\n",
185 " <td>38041757.0</td>\n",
191 " <td>2020-12-07</td>\n",
192 " <td>2020-49</td>\n",
195 " <td>Afghanistan</td>\n",
198 " <td>38041757.0</td>\n",
204 " <td>2020-11-30</td>\n",
205 " <td>2020-48</td>\n",
208 " <td>Afghanistan</td>\n",
211 " <td>38041757.0</td>\n",
217 " <td>2020-11-23</td>\n",
218 " <td>2020-47</td>\n",
221 " <td>Afghanistan</td>\n",
224 " <td>38041757.0</td>\n",
230 " <td>2020-11-16</td>\n",
231 " <td>2020-46</td>\n",
234 " <td>Afghanistan</td>\n",
237 " <td>38041757.0</td>\n",
246 " dateRep year_week cases_weekly deaths_weekly countriesAndTerritories \\\n",
247 "0 2020-12-14 2020-50 1757 71 Afghanistan \n",
248 "1 2020-12-07 2020-49 1672 137 Afghanistan \n",
249 "2 2020-11-30 2020-48 1073 68 Afghanistan \n",
250 "3 2020-11-23 2020-47 1368 69 Afghanistan \n",
251 "4 2020-11-16 2020-46 1164 61 Afghanistan \n",
253 " geoId countryterritoryCode popData2019 continentExp \\\n",
254 "0 AF AFG 38041757.0 Asia \n",
255 "1 AF AFG 38041757.0 Asia \n",
256 "2 AF AFG 38041757.0 Asia \n",
257 "3 AF AFG 38041757.0 Asia \n",
258 "4 AF AFG 38041757.0 Asia \n",
260 " notification_rate_per_100000_population_14-days \n",
268 "execution_count": 4847,
270 "output_type": "execute_result"
279 "execution_count": 4848,
287 "dateRep datetime64[ns]\n",
288 "year_week object\n",
289 "cases_weekly int64\n",
290 "deaths_weekly int64\n",
291 "countriesAndTerritories object\n",
293 "countryterritoryCode object\n",
294 "popData2019 float64\n",
295 "continentExp object\n",
296 "notification_rate_per_100000_population_14-days float64\n",
300 "execution_count": 4848,
302 "output_type": "execute_result"
311 "execution_count": 4849,
318 "evalue": "'Only a column name can be used for the key in a dtype mappings argument.'",
319 "output_type": "error",
321 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
322 "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
323 "\u001b[0;32m<ipython-input-4849-4ccdef75f4f0>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;34m'countryterritoryCode'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m'popData2019'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mint64\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m 'continentExp': str })\n\u001b[0m",
324 "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36mastype\u001b[0;34m(self, dtype, copy, errors, **kwargs)\u001b[0m\n\u001b[1;32m 5855\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcol_name\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5856\u001b[0m raise KeyError(\n\u001b[0;32m-> 5857\u001b[0;31m \u001b[0;34m\"Only a column name can be used for the \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5858\u001b[0m \u001b[0;34m\"key in a dtype mappings argument.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5859\u001b[0m )\n",
325 "\u001b[0;31mKeyError\u001b[0m: 'Only a column name can be used for the key in a dtype mappings argument.'"
330 "# raw_data = raw_data.astype({'dateRep': np.datetime64, \n",
331 "# 'day': np.int64, \n",
332 "# 'month': np.int64, \n",
333 "# 'year': np.int64, \n",
334 "# 'cases': np.int64, \n",
335 "# 'deaths': np.int64, \n",
336 "# 'countriesAndTerritories': str, \n",
337 "# 'geoId': str, \n",
338 "# 'countryterritoryCode': str, \n",
339 "# 'popData2019': np.int64, \n",
340 "# 'continentExp': str })\n",
341 "raw_data = raw_data.astype({'dateRep': np.datetime64, \n",
342 " 'day': np.int64, \n",
343 " 'month': np.int64, \n",
344 " 'year': np.int64, \n",
345 " 'cases': np.int64, \n",
346 " 'deaths': np.int64, \n",
347 " 'countriesAndTerritories': str, \n",
349 " 'countryterritoryCode': str, \n",
350 " 'popData2019': np.int64, \n",
351 " 'continentExp': str })"
356 "execution_count": null,
367 "execution_count": null,
373 "raw_data[((raw_data.geoId == 'UK') & (raw_data.dateRep >= '2020-07-10'))]"
378 "execution_count": null,
384 "# raw_data = raw_data[~ ((raw_data.geoId == 'ES') & (raw_data.dateRep >= '2020-05-22'))]"
389 "execution_count": null,
395 "base_data = raw_data.set_index(['geoId', 'dateRep'])\n",
396 "base_data.sort_index(inplace=True)\n",
402 "execution_count": null,
408 "base_data.loc['ES'].loc['2020-05-10':]"
413 "execution_count": null,
419 "countries = raw_data[['geoId', 'countriesAndTerritories', 'popData2019', 'continentExp']]\n",
420 "countries = countries[countries['popData2019'] != '']\n",
421 "countries = countries.drop_duplicates()\n",
422 "countries.set_index('geoId', inplace=True)\n",
423 "countries = countries.astype({'popData2019': 'int64'})\n",
429 "execution_count": null,
440 "execution_count": null,
446 "countries[countries.countriesAndTerritories == 'Finland']"
451 "execution_count": null,
457 "countries.loc[COUNTRIES_OF_INTEREST]"
462 "execution_count": null,
468 "countries[countries.continentExp == 'America'].index"
473 "execution_count": null,
479 "data_by_date = base_data[['cases', 'deaths']]\n",
480 "data_by_date.head()"
485 "execution_count": null,
491 "data_by_date.loc['UK']"
496 "execution_count": null,
502 "# data_by_date.deaths.drop_duplicates().sort_values().to_csv('dth.csv', header=True)"
507 "execution_count": null,
513 "data_by_date.groupby(level=0).cumsum()"
518 "execution_count": null,
524 "data_by_date = data_by_date.merge(\n",
525 " data_by_date.groupby(level=0).cumsum(), \n",
526 " suffixes=('', '_culm'), \n",
527 " left_index=True, right_index=True)\n",
533 "execution_count": null,
539 "data_by_date = data_by_date.merge(\n",
540 " data_by_date[['cases', 'deaths']].groupby(level=0).diff(), \n",
541 " suffixes=('', '_diff'), \n",
542 " left_index=True, right_index=True)\n",
548 "execution_count": null,
554 "data_by_date.loc['UK', '2020-04-17']"
559 "execution_count": null,
565 "data_by_date.loc['UK']"
570 "execution_count": null,
576 "# data_by_date[data_by_date.deaths_culm > DEATH_COUNT_THRESHOLD]"
581 "execution_count": null,
587 "# days_since_threshold = data_by_date[data_by_date.deaths_culm > DEATH_COUNT_THRESHOLD].groupby(level=0).cumcount()\n",
588 "# days_since_threshold.rename('since_threshold', inplace=True)"
593 "execution_count": null,
599 "dbd = data_by_date[data_by_date.deaths_culm > DEATH_COUNT_THRESHOLD].reset_index(level=1)\n",
600 "dbd['since_threshold'] = dbd.dateRep\n",
601 "dbd.set_index('dateRep', append=True, inplace=True)\n",
602 "dbd.sort_index(inplace=True)\n",
603 "days_since_threshold = dbd.groupby(level=0).diff().since_threshold.dt.days.fillna(0).astype(int).groupby(level=0).cumsum()\n",
604 "# days_since_threshold.groupby(level=0).cumsum()\n",
606 "# days_since_threshold = dbd.rename('since_threshold')\n",
607 "days_since_threshold"
612 "execution_count": null,
618 "# days_since_threshold = (data_by_date[data_by_date.deaths_culm > DEATH_COUNT_THRESHOLD]\n",
619 "# .reset_index(level=1).groupby(level=0)\n",
620 "# .diff().dateRep.dt.days\n",
621 "# .groupby(level=0).cumcount()\n",
623 "# days_since_threshold.rename('since_threshold', inplace=True)\n",
624 "# days_since_threshold"
629 "execution_count": null,
635 "data_since_threshold = data_by_date.merge(days_since_threshold, \n",
636 " left_index=True, right_index=True)\n",
637 "data_since_threshold"
642 "execution_count": null,
648 "data_since_threshold = data_since_threshold.set_index('since_threshold', append=True\n",
649 " ).reorder_levels(['since_threshold', 'geoId', 'dateRep']\n",
650 " ).reset_index('dateRep')\n",
651 "data_since_threshold.sort_index(inplace=True)\n",
652 "data_since_threshold"
657 "execution_count": null,
663 "data_since_threshold.loc[(slice(None), ['UK', 'DE', 'IT']), :]"
668 "execution_count": null,
674 "data_since_threshold.loc[(slice(None), ['ES']), :].tail(8)"
679 "execution_count": null,
685 "data_since_threshold.loc[(slice(None), ['UK', 'DE', 'IT']), ['deaths_culm']].unstack().plot(logy=True)"
690 "execution_count": null,
696 "# deaths = data_since_threshold.loc[(slice(None), ['UK', 'DE', 'IT', 'IE']), ['deaths_culm']].unstack().xs('deaths_culm', axis=1, drop_level=True)"
701 "execution_count": null,
707 "deaths = data_since_threshold.loc[(slice(None), COUNTRIES_ALL), ['deaths_culm']].unstack().sort_index().xs('deaths_culm', axis=1, drop_level=True)\n",
708 "deaths_by_date = data_by_date.loc[COUNTRIES_ALL, ['deaths_culm']].unstack().sort_index().xs('deaths_culm', axis=1, drop_level=True).T"
713 "execution_count": null,
719 "cases = data_since_threshold.loc[(slice(None), COUNTRIES_ALL), ['cases_culm']].unstack().sort_index().xs('cases_culm', axis=1, drop_level=True)\n",
720 "cases_by_date = data_by_date.loc[ COUNTRIES_ALL, ['cases_culm']].unstack().sort_index().xs('cases_culm', axis=1, drop_level=True).T"
725 "execution_count": null,
731 "COUNTRIES_AMERICAS_DEAD = list(set(deaths.columns) & set(COUNTRIES_AMERICAS))"
736 "execution_count": null,
742 "data_since_threshold.reset_index().merge(countries, on='geoId').set_index(['since_threshold', 'geoId'])"
747 "execution_count": null,
753 "data_since_threshold.reset_index().merge(countries, on='geoId').set_index(['since_threshold', 'geoId']).sort_index(inplace=True)"
758 "execution_count": null,
764 "data_since_threshold_per_capita = data_since_threshold.reset_index().merge(countries, on='geoId').set_index(['since_threshold', 'geoId'])\n",
765 "data_since_threshold_per_capita['cases_culm_pc'] = data_since_threshold_per_capita.cases_culm / data_since_threshold_per_capita.popData2019\n",
766 "data_since_threshold_per_capita['deaths_culm_pc'] = data_since_threshold_per_capita.deaths_culm / data_since_threshold_per_capita.popData2019\n",
767 "data_since_threshold_per_capita"
772 "execution_count": null,
778 "deaths_pc = data_since_threshold_per_capita.loc[(slice(None), ['UK', 'DE', 'IT', 'IE']), ['deaths_culm_pc']].unstack().sort_index().xs('deaths_culm_pc', axis=1, drop_level=True)"
783 "execution_count": null,
794 "execution_count": null,
800 "deaths_pc = data_since_threshold_per_capita.loc[(slice(None), COUNTRIES_ALL), ['deaths_culm_pc']].unstack().xs('deaths_culm_pc', axis=1, drop_level=True)"
805 "execution_count": null,
811 "deaths[COUNTRIES_CORE].plot()"
816 "execution_count": null,
822 "deaths[COUNTRIES_FRIENDS].plot()"
827 "execution_count": null,
833 "ax = deaths[COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
834 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
835 "for c in COUNTRIES_FRIENDS:\n",
836 " lvi = deaths[c].last_valid_index()\n",
837 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = f\"{c}: {deaths[c][lvi]:.0f}\")\n",
838 "# plt.savefig('covid_deaths_total_linear.png') "
843 "execution_count": null,
849 "ax = deaths[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
850 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
851 "for c in COUNTRIES_CORE:\n",
852 " lvi = deaths[c].last_valid_index()\n",
853 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = f\"{c}: {deaths[c][lvi]:.0f}\")\n",
854 "# plt.savefig('covid_deaths_total_linear.png') "
859 "execution_count": null,
865 "ax = deaths_by_date.loc['2020-03-15':, COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
866 "# data_by_date.loc[COUNTRIES_CORE]\n",
867 "# deaths_by_date = data_by_date.loc[COUNTRIES_ALL, ['deaths_culm']].unstack().sort_index().xs('deaths_culm', axis=1, drop_level=True)\n",
868 "ax.set_xlabel(f\"Date\")\n",
869 "for c in COUNTRIES_CORE:\n",
870 " lvi = deaths_by_date[c].last_valid_index()\n",
871 " ax.text(x = lvi + pd.Timedelta(days=1), y = deaths_by_date[c][lvi], s = f\"{c}: {deaths_by_date[c][lvi]:.0f}\")\n",
872 "plt.savefig('covid_deaths_total_linear.png') "
877 "execution_count": null,
883 "deaths_prime = deaths[COUNTRIES_CORE].copy()\n",
884 "deaths_prime.loc[73:, 'ES'] = np.NaN\n",
885 "# deaths_prime['ES'][70:]"
890 "execution_count": null,
896 "ax = deaths_prime[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
897 "for c in COUNTRIES_CORE:\n",
898 " lvi = deaths_prime[c].last_valid_index()\n",
899 " ax.text(x = lvi + 1, y = deaths_prime[c][lvi], s = f\"{c}: {deaths_prime[c][lvi]:.0f}\")\n",
900 "# plt.savefig('covid_deaths_total_linear.png') "
905 "execution_count": null,
911 "ax = cases[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Total cases, linear\")\n",
912 "for c in COUNTRIES_CORE:\n",
913 " lvi = cases[c].last_valid_index()\n",
914 " ax.text(x = lvi + 1, y = cases[c][lvi], s = c)\n",
915 "plt.savefig('covid_cases_total_linear.png') "
920 "execution_count": null,
926 "ax = deaths[COUNTRIES_AMERICAS_DEAD].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
927 "for c in COUNTRIES_AMERICAS_DEAD:\n",
928 " lvi = deaths[c].last_valid_index()\n",
929 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
930 "# plt.savefig('covid_deaths_total_linear.png') "
935 "execution_count": null,
941 "ax = deaths[COUNTRIES_CORE + ['BR', 'MX']].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
942 "for c in COUNTRIES_CORE + ['BR', 'MX']:\n",
943 " lvi = deaths[c].last_valid_index()\n",
944 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
945 "# plt.savefig('covid_deaths_total_linear.png') "
950 "execution_count": null,
956 "ax = deaths[COUNTRIES_NORDIC].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
957 "for c in COUNTRIES_NORDIC:\n",
958 " lvi = deaths[c].last_valid_index()\n",
959 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
960 "# plt.savefig('covid_deaths_total_linear.png') "
965 "execution_count": null,
971 "ax = deaths[COUNTRIES_OF_INTEREST].plot(figsize=(10, 6), title=\"Total deaths, linear\")\n",
972 "for c in COUNTRIES_OF_INTEREST:\n",
973 " lvi = deaths[c].last_valid_index()\n",
974 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
975 "plt.savefig('covid_deaths_total_linear_of_interest.png') "
980 "execution_count": null,
986 "ax = deaths[COUNTRIES_CORE].plot(logy=True, figsize=(10, 6), title=\"Total deaths, log\")\n",
987 "for c in COUNTRIES_CORE:\n",
988 " lvi = deaths[c].last_valid_index()\n",
989 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
991 "plt.savefig('covid_deaths_total_log.png')"
996 "execution_count": null,
1002 "ylim = (5*10**3, 5*10**4)\n",
1003 "ax = deaths[COUNTRIES_CORE].plot(logy=True, figsize=(10, 6), ylim=ylim, title=\"Total deaths, log\")\n",
1004 "for c in COUNTRIES_CORE:\n",
1005 " lvi = deaths[c].last_valid_index()\n",
1006 " if ylim[0] < deaths[c][lvi] < ylim[1]:\n",
1007 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
1009 "# plt.savefig('covid_deaths_total_log.png')"
1013 "cell_type": "code",
1014 "execution_count": null,
1016 "Collapsed": "false"
1020 "ax = deaths[COUNTRIES_FRIENDS].plot(logy=True, figsize=(10, 6), title=\"Total deaths, log\")\n",
1021 "for c in COUNTRIES_FRIENDS:\n",
1022 " lvi = deaths[c].last_valid_index()\n",
1023 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
1025 "# plt.savefig('covid_deaths_total_log.png')"
1029 "cell_type": "code",
1030 "execution_count": null,
1032 "Collapsed": "false"
1036 "ax = deaths[COUNTRIES_NORDIC].plot(logy=True, figsize=(10, 6), title=\"Total deaths, log\")\n",
1037 "for c in COUNTRIES_NORDIC:\n",
1038 " lvi = deaths[c].last_valid_index()\n",
1039 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
1041 "# plt.savefig('covid_deaths_total_log.png')"
1045 "cell_type": "code",
1046 "execution_count": null,
1048 "Collapsed": "false"
1052 "ax = deaths[COUNTRIES_OF_INTEREST].plot(logy=True, figsize=(10, 6), title=\"Total deaths, log\")\n",
1053 "for c in COUNTRIES_OF_INTEREST:\n",
1054 " lvi = deaths[c].last_valid_index()\n",
1055 " ax.text(x = lvi + 1, y = deaths[c][lvi], s = c)\n",
1057 "plt.savefig('covid_deaths_total_log.png')"
1061 "cell_type": "code",
1062 "execution_count": null,
1064 "Collapsed": "false"
1068 "ax = deaths_pc.plot(figsize=(10, 6), title=\"Deaths per capita, linear\")\n",
1069 "for c in deaths_pc.columns:\n",
1070 " lvi = deaths_pc[c].last_valid_index()\n",
1071 " ax.text(x = lvi + 1, y = deaths_pc[c][lvi], s = c)\n",
1072 "plt.savefig('covid_deaths_per_capita_linear.png')"
1076 "cell_type": "code",
1077 "execution_count": null,
1079 "Collapsed": "false"
1083 "ax = deaths_pc.plot(logy=True, figsize=(10, 6), title=\"Deaths per capita, log\")\n",
1084 "for c in deaths_pc.columns:\n",
1085 " lvi = deaths_pc[c].last_valid_index()\n",
1086 " ax.text(x = lvi + 1, y = deaths_pc[c][lvi], s = c)"
1090 "cell_type": "code",
1091 "execution_count": null,
1093 "Collapsed": "false"
1097 "deaths_pc[['UK', 'IE']].plot( figsize=(10, 6), title=\"Deaths per capita, linear\")"
1101 "cell_type": "code",
1102 "execution_count": null,
1104 "Collapsed": "false"
1108 "deaths_pc[['UK', 'IE']].plot(logy=True, figsize=(10, 6), title=\"Deaths per capita, log\")"
1112 "cell_type": "code",
1113 "execution_count": null,
1115 "Collapsed": "false"
1119 "deaths[['UK', 'ES', 'IT']].plot(logy=True, figsize=(10, 6), title=\"Deaths, log\")\n",
1120 "plt.savefig('covid_deaths_selected_log.png')"
1124 "cell_type": "code",
1125 "execution_count": null,
1127 "Collapsed": "false"
1131 "deaths[['UK', 'ES', 'IT', 'MX']].plot(logy=True, figsize=(10, 6), title=\"Deaths, log\")"
1135 "cell_type": "code",
1136 "execution_count": null,
1138 "Collapsed": "false"
1142 "data_since_threshold.loc[(slice(None), ['UK', 'DE', 'IT']), :]"
1146 "cell_type": "code",
1147 "execution_count": null,
1149 "Collapsed": "false"
1153 "data_since_threshold['deaths_m4'] = data_since_threshold.groupby(level=1)['deaths'].transform(lambda x: x.rolling(4, 1).mean())\n",
1154 "data_since_threshold['deaths_m7'] = data_since_threshold.groupby(level=1)['deaths'].transform(lambda x: x.rolling(7, 1).mean())\n",
1155 "data_since_threshold['cases_m7'] = data_since_threshold.groupby(level=1)['cases'].transform(lambda x: x.rolling(7, 1).mean())\n",
1156 "# data_since_threshold['deaths_diff_m4'] = data_since_threshold.groupby(level=1)['deaths_diff'].transform(lambda x: x.rolling(4, 1).mean())\n",
1157 "# data_since_threshold['deaths_diff_m7'] = data_since_threshold.groupby(level=1)['deaths_diff'].transform(lambda x: x.rolling(7, 1).mean())\n",
1158 "data_since_threshold.loc[(slice(None), ['UK', 'DE', 'IT']), :]"
1162 "cell_type": "code",
1163 "execution_count": null,
1165 "Collapsed": "false"
1169 "deaths_m4 = (data_since_threshold.loc[(slice(None), COUNTRIES_ALL), ['deaths_m4']]\n",
1170 " .unstack().sort_index().xs('deaths_m4', axis=1, drop_level=True))"
1174 "cell_type": "code",
1175 "execution_count": null,
1177 "Collapsed": "false"
1181 "deaths_m7 = (data_since_threshold.loc[(slice(None), COUNTRIES_ALL), ['deaths_m7']]\n",
1182 " .unstack().sort_index().xs('deaths_m7', axis=1, drop_level=True))"
1186 "cell_type": "code",
1187 "execution_count": null,
1189 "Collapsed": "false"
1193 "cases_m7 = (data_since_threshold.loc[(slice(None), COUNTRIES_ALL), ['cases_m7']]\n",
1194 " .unstack().sort_index().xs('cases_m7', axis=1, drop_level=True))"
1198 "cell_type": "code",
1199 "execution_count": null,
1201 "Collapsed": "false"
1205 "data_by_date['cases_m7'] = data_by_date.groupby(level=0)['cases'].transform(lambda x: x.rolling(7, 1).mean())\n",
1206 "data_by_date['deaths_m7'] = data_by_date.groupby(level=0)['deaths'].transform(lambda x: x.rolling(7, 1).mean())\n",
1211 "cell_type": "code",
1212 "execution_count": null,
1214 "Collapsed": "false"
1218 "data_by_date.loc[('UK', '2020-07-15'):'UK', 'cases'].plot()"
1222 "cell_type": "code",
1223 "execution_count": null,
1225 "Collapsed": "false"
1229 "cases_by_date_m7 = data_by_date.loc[COUNTRIES_ALL, 'cases_m7'].unstack(level=0).sort_index()\n",
1230 "cases_by_date_m7[COUNTRIES_CORE].plot()"
1234 "cell_type": "code",
1235 "execution_count": null,
1237 "Collapsed": "false"
1241 "deaths_by_date_m7 = data_by_date.loc[COUNTRIES_ALL, 'deaths_m7'].unstack(level=0).sort_index()\n",
1242 "deaths_by_date_m7[COUNTRIES_CORE].plot()"
1246 "cell_type": "code",
1247 "execution_count": null,
1249 "Collapsed": "false"
1253 "ax = deaths_m4.plot(figsize=(10, 6), title=\"Deaths per day, 4 day moving average\")\n",
1254 "for c in deaths_m4.columns:\n",
1255 " lvi = deaths_m4[c].last_valid_index()\n",
1256 " ax.text(x = lvi + 1, y = deaths_m4[c][lvi], s = c)\n",
1257 "plt.savefig('covid_deaths_per_day.png') "
1261 "cell_type": "code",
1262 "execution_count": null,
1264 "Collapsed": "false"
1268 "ax = deaths_m4[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Deaths per day, 4 day moving average\")\n",
1269 "for c in COUNTRIES_CORE:\n",
1270 " lvi = deaths_m4[c].last_valid_index()\n",
1271 " ax.text(x = lvi + 1, y = deaths_m4[c][lvi], s = c)\n",
1272 "plt.savefig('covid_deaths_per_day-core.png') "
1276 "cell_type": "code",
1277 "execution_count": null,
1279 "Collapsed": "false"
1283 "ax = deaths_m4[COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Deaths per day, 4 day moving average\")\n",
1284 "for c in COUNTRIES_FRIENDS:\n",
1285 " lvi = deaths_m4[c].last_valid_index()\n",
1286 " ax.text(x = lvi + 1, y = deaths_m4[c][lvi], s = c)\n",
1287 "# plt.savefig('covid_deaths_per_day-friends.png') "
1291 "cell_type": "code",
1292 "execution_count": null,
1294 "Collapsed": "false"
1298 "C7s = 'ES FR IT UK'.split()\n",
1299 "ax = deaths_m7[C7s].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")\n",
1301 " lvi = deaths_m7[c].last_valid_index()\n",
1302 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = c)\n",
1303 "# plt.savefig('covid_deaths_per_day-friends.png') "
1307 "cell_type": "code",
1308 "execution_count": null,
1310 "Collapsed": "false"
1314 "ax = deaths_m7[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")\n",
1315 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
1316 "for c in COUNTRIES_CORE:\n",
1317 " lvi = deaths_m7[c].last_valid_index()\n",
1318 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = c)\n",
1319 "# plt.axhline(0, color='0.7')\n",
1320 "plt.savefig('covid_deaths_per_day_7.png') "
1324 "cell_type": "code",
1325 "execution_count": null,
1327 "Collapsed": "false"
1331 "ax = deaths_m7[COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")\n",
1332 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
1333 "for c in COUNTRIES_FRIENDS:\n",
1334 " lvi = deaths_m7[c].last_valid_index()\n",
1335 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = c)\n",
1336 "# plt.axhline(0, color='0.7')\n",
1337 "plt.savefig('covid_deaths_per_day-friends.png') "
1341 "cell_type": "code",
1342 "execution_count": null,
1344 "Collapsed": "false"
1348 "deaths_m7_prime = deaths_m7[COUNTRIES_CORE].copy()\n",
1349 "deaths_m7_prime.loc[73:, 'ES'] = np.NaN\n",
1350 "deaths_m7_prime['ES'][70:]"
1354 "cell_type": "code",
1355 "execution_count": null,
1357 "Collapsed": "false"
1361 "ax = deaths_m7_prime[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")\n",
1362 "for c in COUNTRIES_CORE:\n",
1363 " lvi = deaths_m7_prime[c].last_valid_index()\n",
1364 " ax.text(x = lvi + 1, y = deaths_m7_prime[c][lvi], s = c)\n",
1365 "plt.savefig('covid_deaths_per_day_7.png') # see below for where this is written, with the projection"
1369 "cell_type": "code",
1370 "execution_count": null,
1372 "Collapsed": "false"
1376 "ax = deaths_by_date_m7.loc['2020-03-01':, COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")\n",
1377 "ax.set_xlabel('Date')\n",
1378 "for c in COUNTRIES_CORE:\n",
1379 " lvi = deaths_by_date_m7[c].last_valid_index()\n",
1380 " ax.text(x = lvi + pd.Timedelta(days=1), y = deaths_by_date_m7[c][lvi], s = c)\n",
1381 "plt.savefig('covid_deaths_per_day_7.png') "
1385 "cell_type": "code",
1386 "execution_count": null,
1388 "Collapsed": "false"
1392 "ax = deaths_m7[COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")\n",
1393 "for c in COUNTRIES_FRIENDS:\n",
1394 " lvi = deaths_m7[c].last_valid_index()\n",
1395 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = c)\n",
1396 "plt.savefig('covid_deaths_per_day_friends_7.png') "
1400 "cell_type": "code",
1401 "execution_count": null,
1403 "Collapsed": "false"
1407 "ax = deaths_m7[COUNTRIES_CORE + ['BR', 'MX']].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")\n",
1408 "for c in COUNTRIES_CORE + ['BR', 'MX']:\n",
1409 " lvi = deaths_m7[c].last_valid_index()\n",
1410 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = c)\n",
1411 "# plt.savefig('covid_deaths_per_day_7.png') "
1415 "cell_type": "code",
1416 "execution_count": null,
1418 "Collapsed": "false"
1422 "ax = deaths_by_date_m7.iloc[-30:][COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")#, ylim=(-10, 100))\n",
1423 "ax.set_xlabel(\"Date\")\n",
1425 "text_x_pos = deaths_by_date_m7.last_valid_index() + pd.Timedelta(days=1)\n",
1427 "for c in COUNTRIES_CORE:\n",
1428 " lvi = deaths_by_date_m7[c].last_valid_index()\n",
1429 "# if c != 'ES':\n",
1430 " ax.text(x = text_x_pos, y = deaths_by_date_m7[c][lvi], s = f\"{c}: {deaths_by_date_m7[c][lvi]:.0f}\")\n",
1431 "plt.savefig('deaths_by_date_last_30_days.png') "
1435 "cell_type": "code",
1436 "execution_count": null,
1438 "Collapsed": "false"
1442 "ax = deaths_by_date_m7.iloc[-30:][COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\")#, ylim=(-10, 100))\n",
1443 "ax.set_xlabel(\"Date\")\n",
1445 "text_x_pos = deaths_by_date_m7.last_valid_index() + pd.Timedelta(days=1)\n",
1447 "for c in COUNTRIES_FRIENDS:\n",
1448 " lvi = deaths_by_date_m7[c].last_valid_index()\n",
1449 "# if c != 'ES':\n",
1450 " ax.text(x = text_x_pos, y = deaths_by_date_m7[c][lvi], s = f\"{c}: {deaths_by_date_m7[c][lvi]:.0f}\")\n",
1451 "plt.savefig('deaths_by_date_last_30_days_friends.png') "
1455 "cell_type": "code",
1456 "execution_count": null,
1458 "Collapsed": "false"
1462 "ax = cases_m7[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Cases per day, 7 day moving average\")\n",
1463 "for c in COUNTRIES_CORE:\n",
1464 " lvi = cases_m7[c].last_valid_index()\n",
1465 " ax.text(x = lvi + 1, y = cases_m7[c][lvi], s = c)\n",
1466 "plt.savefig('covid_cases_per_day-core.png') "
1470 "cell_type": "code",
1471 "execution_count": null,
1473 "Collapsed": "false"
1477 "ax = cases_m7[COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Cases per day, 7 day moving average\")\n",
1478 "for c in COUNTRIES_FRIENDS:\n",
1479 " lvi = cases_m7[c].last_valid_index()\n",
1480 " ax.text(x = lvi + 1, y = cases_m7[c][lvi], s = c)\n",
1481 "plt.savefig('covid_cases_per_day-core.png') "
1485 "cell_type": "code",
1486 "execution_count": null,
1488 "Collapsed": "false"
1492 "ax = cases_by_date_m7.iloc[-30:][COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Cases per day, 7 day moving average\")#, ylim=(-10, 100))\n",
1493 "ax.set_xlabel(\"Date\")\n",
1495 "text_x_pos = cases_by_date_m7.last_valid_index() + pd.Timedelta(days=1)\n",
1497 "for c in COUNTRIES_FRIENDS:\n",
1498 " lvi = cases_by_date_m7[c].last_valid_index()\n",
1499 "# if c != 'ES':\n",
1500 " ax.text(x = text_x_pos, y = cases_by_date_m7[c][lvi], s = f\"{c}: {cases_by_date_m7[c][lvi]:.0f}\")\n",
1501 "plt.savefig('cases_by_date_last_30_days_friends.png') "
1505 "cell_type": "code",
1506 "execution_count": null,
1508 "Collapsed": "false"
1512 "def gmean_scale(items):\n",
1513 " return gmean(items) / items[-1]"
1517 "cell_type": "code",
1518 "execution_count": null,
1520 "Collapsed": "false"
1524 "def doubling_time(df):\n",
1525 " return np.log(2) / np.log((df.deaths_culm + df.deaths_g4) / df.deaths_culm)\n",
1527 "def doubling_time_7(df):\n",
1528 " return np.log(2) / np.log((df.deaths_culm + df.deaths_g7) / df.deaths_culm)"
1532 "cell_type": "code",
1533 "execution_count": null,
1535 "Collapsed": "false"
1539 "# data_since_threshold['deaths_g4'] = data_since_threshold.groupby(level=1)['deaths'].transform(lambda x: x.rolling(4, 1).apply(gmean_scale, raw=True))\n",
1540 "# data_since_threshold.loc[(slice(None), ['UK', 'DE', 'IT']), :]"
1544 "cell_type": "code",
1545 "execution_count": null,
1547 "Collapsed": "false"
1551 "data_since_threshold['deaths_g4'] = data_since_threshold.groupby(level=1)['deaths'].transform(lambda x: x.rolling(4, 1).apply(gmean, raw=True))\n",
1552 "data_since_threshold['deaths_g7'] = data_since_threshold.groupby(level=1)['deaths'].transform(lambda x: x.rolling(7, 1).apply(gmean, raw=True))\n",
1553 "data_since_threshold.loc[(slice(None), ['UK', 'DE', 'IT']), :]"
1557 "cell_type": "code",
1558 "execution_count": null,
1560 "Collapsed": "false"
1564 "data_since_threshold['doubling_time'] = data_since_threshold.groupby(level=1).apply(doubling_time).reset_index(level=0, drop=True).sort_index()\n",
1565 "data_since_threshold['doubling_time_7'] = data_since_threshold.groupby(level=1).apply(doubling_time_7).reset_index(level=0, drop=True).sort_index()\n",
1566 "# data_since_threshold.loc[(slice(None), 'UK'), :]"
1570 "cell_type": "code",
1571 "execution_count": null,
1573 "Collapsed": "false"
1577 "data_by_date['deaths_g4'] = data_by_date.groupby(level=0)['deaths'].transform(lambda x: x.rolling(4, 1).apply(gmean, raw=True))\n",
1578 "data_by_date['deaths_g7'] = data_by_date.groupby(level=0)['deaths'].transform(lambda x: x.rolling(7, 1).apply(gmean, raw=True))\n",
1579 "data_by_date['doubling_time'] = data_by_date.groupby(level=0).apply(doubling_time).reset_index(level=0, drop=True).sort_index()\n",
1580 "data_by_date['doubling_time_7'] = data_by_date.groupby(level=0).apply(doubling_time_7).reset_index(level=0, drop=True).sort_index()\n",
1581 "data_by_date.loc['UK']"
1585 "cell_type": "code",
1586 "execution_count": null,
1588 "Collapsed": "false"
1592 "doubling_times = (data_since_threshold.loc[(slice(None), COUNTRIES_OF_INTEREST), ['doubling_time']]\n",
1593 " .unstack().sort_index().xs('doubling_time', axis=1, drop_level=True))\n",
1594 "doubling_times.replace([np.inf, -np.inf], np.nan, inplace=True)"
1598 "cell_type": "code",
1599 "execution_count": null,
1601 "Collapsed": "false"
1605 "doubling_times_7 = (data_since_threshold.loc[(slice(None), COUNTRIES_OF_INTEREST), ['doubling_time_7']]\n",
1606 " .unstack().sort_index().xs('doubling_time_7', axis=1, drop_level=True))\n",
1607 "doubling_times_7.replace([np.inf, -np.inf], np.nan, inplace=True)"
1611 "cell_type": "code",
1612 "execution_count": null,
1614 "Collapsed": "false"
1618 "ax = doubling_times.plot(figsize=(10, 6), title=\"Doubling times, 4 day average\")\n",
1619 "for c in doubling_times.columns:\n",
1620 " lvi = doubling_times[c].last_valid_index()\n",
1621 " ax.text(x = lvi + 1, y = doubling_times[c][lvi], s = c)\n",
1622 "# plt.savefig('covid_deaths_per_day.png') "
1626 "cell_type": "code",
1627 "execution_count": null,
1629 "Collapsed": "false"
1633 "ax = doubling_times_7[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Doubling times, 7 day average\")\n",
1634 "ax.legend(loc=\"upper left\")\n",
1635 "for c in COUNTRIES_CORE:\n",
1636 " lvi = doubling_times_7[c].last_valid_index()\n",
1637 " ax.text(x = lvi + 1, y = doubling_times_7[c][lvi], s = c)\n",
1638 "plt.savefig('covid_doubling_times_7.png') "
1642 "cell_type": "code",
1643 "execution_count": null,
1645 "Collapsed": "false"
1649 "ax = doubling_times[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Doubling times, 4 day average\")\n",
1650 "for c in COUNTRIES_CORE:\n",
1651 " lvi = doubling_times[c].last_valid_index()\n",
1652 " ax.text(x = lvi + 1, y = doubling_times[c][lvi], s = c)\n",
1653 "plt.savefig('covid_doubling_times.png') "
1657 "cell_type": "code",
1658 "execution_count": null,
1660 "Collapsed": "false"
1664 "ax = doubling_times[COUNTRIES_FRIENDS].plot(figsize=(10, 6), title=\"Doubling times\")\n",
1665 "for c in COUNTRIES_FRIENDS:\n",
1666 " lvi = doubling_times[c].last_valid_index()\n",
1667 " ax.text(x = lvi + 1, y = doubling_times[c][lvi], s = c)\n",
1668 "plt.savefig('covid_doubling_times_friends.png')"
1672 "cell_type": "code",
1673 "execution_count": null,
1675 "Collapsed": "false"
1679 "ax = doubling_times[C7s].plot(figsize=(10, 6), title=\"Doubling times\")\n",
1681 " lvi = doubling_times[c].last_valid_index()\n",
1682 " ax.text(x = lvi + 1, y = doubling_times[c][lvi], s = c)\n",
1683 "# plt.savefig('covid_doubling_times_friends.png')"
1687 "cell_type": "code",
1688 "execution_count": null,
1690 "Collapsed": "false"
1694 "# deaths_diff_m4 = (data_since_threshold.loc[(slice(None), COUNTRIES_ALL), ['deaths_diff_m4']]\n",
1695 "# .unstack().sort_index().xs('deaths_diff_m4', axis=1, drop_level=True))"
1699 "cell_type": "code",
1700 "execution_count": null,
1702 "Collapsed": "false"
1706 "# deaths_diff_m7 = (data_since_threshold.loc[(slice(None), COUNTRIES_ALL), ['deaths_diff_m7']]\n",
1707 "# .unstack().sort_index().xs('deaths_diff_m7', axis=1, drop_level=True))"
1711 "cell_type": "code",
1712 "execution_count": null,
1714 "Collapsed": "false"
1722 "cell_type": "code",
1723 "execution_count": null,
1725 "Collapsed": "false"
1729 "# data_since_threshold.replace([np.inf, -np.inf], np.nan).groupby(level=1).last().loc[COUNTRIES_ALL]#, [doubling_time]]"
1733 "cell_type": "code",
1734 "execution_count": null,
1736 "Collapsed": "false"
1740 "dstl = data_since_threshold.replace([np.inf, -np.inf], np.nan).groupby(level=1).last()\n",
1741 "dstl.loc[dstl.index.intersection(COUNTRIES_ALL)]"
1745 "cell_type": "code",
1746 "execution_count": null,
1748 "Collapsed": "false"
1752 "# data_since_threshold.replace([np.inf, -np.inf], np.nan).groupby(level=1).last().loc[['UK', 'DE', 'IT']]#, [doubling_time]]\n",
1753 "dstl.loc[['UK', 'DE', 'IT', 'FR', 'ES']]"
1757 "cell_type": "code",
1758 "execution_count": null,
1760 "Collapsed": "false"
1764 "data_since_threshold.loc[(slice(None), ['UK']), :].tail(20)"
1768 "cell_type": "code",
1769 "execution_count": null,
1771 "Collapsed": "false"
1775 "data_since_threshold.loc[(slice(None), ['ES']), :].tail(20)"
1779 "cell_type": "markdown",
1781 "Collapsed": "false"
1784 "## Death projections"
1788 "cell_type": "code",
1789 "execution_count": null,
1791 "Collapsed": "false"
1795 "data_since_threshold.loc[(slice(None), ['UK']), :].tail(15)"
1799 "cell_type": "code",
1800 "execution_count": null,
1802 "Collapsed": "false"
1806 "it_since_threshold = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['IT']), :]\n",
1807 "s_end = it_since_threshold.index.max()[0]\n",
1812 "cell_type": "code",
1813 "execution_count": null,
1815 "Collapsed": "false"
1819 "uk_projection = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['UK']), :]\n",
1820 "uk_current_end = uk_projection.index.max()[0] + 1\n",
1821 "# s_start = uk_projection.index.max()[0] + 1\n",
1826 "cell_type": "code",
1827 "execution_count": null,
1829 "Collapsed": "false"
1833 "current_uk_deaths_m7 = uk_projection[uk_projection.deaths_m7 >= 0].iloc[-1].deaths_m7\n",
1834 "current_uk_deaths_m7"
1838 "cell_type": "code",
1839 "execution_count": null,
1841 "Collapsed": "false"
1845 "it_since_threshold[it_since_threshold.deaths_m7 <= current_uk_deaths_m7].loc[60:].first_valid_index()[0]"
1849 "cell_type": "code",
1850 "execution_count": null,
1852 "Collapsed": "false"
1856 "s_start = it_since_threshold[it_since_threshold.deaths_m7 <= current_uk_deaths_m7].loc[60:].first_valid_index()[0]\n",
1861 "cell_type": "code",
1862 "execution_count": null,
1864 "Collapsed": "false"
1868 "s_start_date = data_since_threshold.loc[(89, 'IT'), 'dateRep']# .iloc[0]\n",
1873 "cell_type": "code",
1874 "execution_count": null,
1876 "Collapsed": "false"
1884 "cell_type": "code",
1885 "execution_count": null,
1887 "Collapsed": "false"
1891 "uk_end = s_end - s_start + uk_current_end\n",
1896 "cell_type": "code",
1897 "execution_count": null,
1899 "Collapsed": "false"
1903 "proj = it_since_threshold.loc[(slice(s_start, s_end), slice(None)), ['cases', 'deaths', 'deaths_m7']]\n",
1904 "ndiff = uk_current_end - s_start\n",
1905 "proj.index = pd.MultiIndex.from_tuples([(n + ndiff, 'UK') for n, _ in proj.index], names=proj.index.names)\n",
1910 "cell_type": "code",
1911 "execution_count": null,
1913 "Collapsed": "false"
1917 "it_since_threshold.loc[(slice(s_start - 8, s_start + 2), slice(None)), ['cases', 'deaths', 'deaths_m7']]"
1921 "cell_type": "code",
1922 "execution_count": null,
1924 "Collapsed": "false"
1928 "uk_projection[['cases', 'deaths', 'deaths_m7']].tail()"
1932 "cell_type": "code",
1933 "execution_count": null,
1935 "Collapsed": "false"
1939 "# proj['deaths_m7'] = proj['deaths_m7'] + 20\n",
1944 "cell_type": "markdown",
1946 "Collapsed": "false"
1949 "Projected deaths, UK following IT trend from now."
1953 "cell_type": "code",
1954 "execution_count": null,
1956 "Collapsed": "false"
1960 "uk_projection = uk_projection.append(proj, sort=True)\n",
1961 "uk_projection.deaths.sum()"
1965 "cell_type": "code",
1966 "execution_count": null,
1968 "Collapsed": "false"
1972 "uk_projection = uk_projection.droplevel(1)\n",
1977 "cell_type": "code",
1978 "execution_count": null,
1980 "Collapsed": "false"
1984 "uk_projection.loc[152, 'deaths']"
1988 "cell_type": "markdown",
1990 "Collapsed": "false"
1993 "## Correction for cumulative deaths correction on 14 August"
1997 "cell_type": "code",
1998 "execution_count": null,
2000 "Collapsed": "false"
2004 "# uk_projection.loc[152, 'deaths'] = 50"
2008 "cell_type": "code",
2009 "execution_count": null,
2011 "Collapsed": "false"
2015 "uk_projection['deaths_m7'] = uk_projection['deaths'].transform(lambda x: x.rolling(7, 1).mean())\n",
2016 "uk_projection.loc[(uk_current_end - 20):(uk_current_end + 5)]"
2020 "cell_type": "code",
2021 "execution_count": null,
2023 "Collapsed": "false"
2027 "uk_projection.loc[(uk_current_end - 5):]"
2031 "cell_type": "code",
2032 "execution_count": null,
2034 "Collapsed": "false"
2038 "uk_projection.deaths_m7.plot()"
2042 "cell_type": "code",
2043 "execution_count": null,
2045 "Collapsed": "false"
2049 "proj.droplevel(level=1)"
2053 "cell_type": "code",
2054 "execution_count": null,
2056 "Collapsed": "false"
2060 "ax = deaths_m7[COUNTRIES_CORE].plot()\n",
2061 "# uk_projection['deaths_m7'].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\", label=\"Projection\", style='--', ax=ax)\n",
2062 "proj.droplevel(level=1)['deaths_m7'].plot(figsize=(10, 6), title=\"Deaths per day, 7 day moving average\", label=\"Projection\", style='--', ax=ax)\n",
2063 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
2064 "for c in COUNTRIES_CORE:\n",
2065 " lvi = deaths_m7[c].last_valid_index()\n",
2066 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = c)\n",
2067 "# plt.savefig('covid_deaths_per_day_7.png') "
2071 "cell_type": "code",
2072 "execution_count": null,
2074 "Collapsed": "false"
2078 "it_since_threshold.deaths.sum()"
2082 "cell_type": "markdown",
2084 "Collapsed": "false"
2087 "# Excess deaths calculation"
2091 "cell_type": "code",
2092 "execution_count": null,
2094 "Collapsed": "false"
2098 "with open('excess_deaths.json') as f:\n",
2099 " excess_deaths_data = json.load(f)\n",
2101 "# with open('excess_death_accuracy.json') as f:\n",
2102 "# excess_death_accuracy = json.load(f)\n",
2104 "excess_deaths_data"
2108 "cell_type": "code",
2109 "execution_count": null,
2111 "Collapsed": "false"
2115 "additional_deaths = data_by_date.loc[('UK', excess_deaths_data['end_date']):('UK')].iloc[1:].deaths.sum()\n",
2120 "cell_type": "code",
2121 "execution_count": null,
2123 "Collapsed": "false"
2127 "uk_covid_deaths = data_by_date.loc['UK'].deaths.sum()\n",
2132 "cell_type": "code",
2133 "execution_count": null,
2135 "Collapsed": "false"
2139 "uk_deaths_to_date = int(excess_deaths_data['excess_deaths']) + additional_deaths\n",
2144 "cell_type": "code",
2145 "execution_count": null,
2147 "Collapsed": "false"
2151 "# excess_deaths_upto = '2020-05-08'\n",
2152 "# excess_deaths = 54500"
2156 "cell_type": "code",
2157 "execution_count": null,
2159 "Collapsed": "false"
2163 "# excess_deaths_upto = excess_deaths_data['end_date']\n",
2164 "# excess_deaths = excess_deaths_data['excess_deaths']"
2168 "cell_type": "markdown",
2170 "Collapsed": "false"
2173 "Recorded deaths in period where ONS has reported total deaths"
2177 "cell_type": "code",
2178 "execution_count": null,
2180 "Collapsed": "false"
2184 "# ons_reported_deaths = base_data.loc['UK'][:excess_deaths_upto]['deaths'].sum()\n",
2185 "# ons_reported_deaths"
2189 "cell_type": "code",
2190 "execution_count": null,
2192 "Collapsed": "false"
2196 "# excess_deaths_upto"
2200 "cell_type": "markdown",
2202 "Collapsed": "false"
2205 "## Correction for deaths total correction on 14 August"
2209 "cell_type": "code",
2210 "execution_count": null,
2212 "Collapsed": "false"
2216 "# ons_unreported_deaths_data = base_data.loc['UK'][excess_deaths_upto:].iloc[1:]['deaths']\n",
2217 "# ons_unreported_deaths_data['2020-08-14'] = 50"
2221 "cell_type": "code",
2222 "execution_count": null,
2224 "Collapsed": "false"
2228 "# ons_unreported_deaths = ons_unreported_deaths_data.sum()\n",
2229 "# ons_unreported_deaths"
2233 "cell_type": "code",
2234 "execution_count": null,
2236 "Collapsed": "false"
2240 "# scaled_ons_unreported_deaths = ons_unreported_deaths * excess_death_accuracy\n",
2241 "# scaled_ons_unreported_deaths"
2245 "cell_type": "code",
2246 "execution_count": null,
2248 "Collapsed": "false"
2252 "# uk_deaths_to_date = excess_deaths + scaled_ons_unreported_deaths\n",
2253 "# uk_deaths_to_date"
2257 "cell_type": "code",
2258 "execution_count": null,
2260 "Collapsed": "false"
2264 "# data_since_threshold.loc[(slice(None), 'UK'), :][data_since_threshold.dateRep == excess_deaths_data['end_date']]"
2268 "cell_type": "code",
2269 "execution_count": null,
2271 "Collapsed": "false"
2275 "# data_since_threshold[data_since_threshold.dateRep == excess_deaths_data['end_date']].loc[(slice(None), 'UK'), :]"
2279 "cell_type": "code",
2280 "execution_count": null,
2282 "Collapsed": "false"
2286 "# ons_unreported_start = data_since_threshold[data_since_threshold.dateRep == excess_deaths_data['end_date']].loc[(slice(None), 'UK'), :].first_valid_index()[0] + 1\n",
2287 "# ons_unreported_start"
2291 "cell_type": "code",
2292 "execution_count": null,
2294 "Collapsed": "false"
2298 "# unreported_projected_deaths = uk_projection.loc[ons_unreported_start:].deaths.sum()\n",
2299 "# unreported_projected_deaths"
2303 "cell_type": "code",
2304 "execution_count": null,
2306 "Collapsed": "false"
2310 "# unreported_projected_deaths_scaled = unreported_projected_deaths * excess_death_accuracy\n",
2311 "# unreported_projected_deaths_scaled"
2315 "cell_type": "code",
2316 "execution_count": null,
2318 "Collapsed": "false"
2322 "# uk_projection.loc[(s_start):].deaths.sum()"
2326 "cell_type": "code",
2327 "execution_count": null,
2329 "Collapsed": "false"
2333 "# deaths_actual_projected_scaled = uk_deaths_to_date + uk_projection.loc[(s_start):].deaths.sum() * excess_death_accuracy\n",
2334 "# deaths_actual_projected_scaled"
2338 "cell_type": "code",
2339 "execution_count": null,
2341 "Collapsed": "false"
2345 "# excess_deaths / reported_deaths"
2349 "cell_type": "markdown",
2351 "Collapsed": "false"
2354 "True deaths to date, if we follow the scaling of excess deaths over reported deaths so far."
2358 "cell_type": "code",
2359 "execution_count": null,
2361 "Collapsed": "false"
2365 "# uk_covid_deaths = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['UK']), 'deaths_culm'].iloc[-1]\n",
2370 "cell_type": "code",
2371 "execution_count": null,
2373 "Collapsed": "false"
2377 "# uk_covid_deaths_scaled = excess_deaths + unreported_deaths * excess_death_accuracy\n",
2378 "# uk_covid_deaths_scaled"
2382 "cell_type": "code",
2383 "execution_count": null,
2385 "Collapsed": "false"
2389 "# data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['IT']), 'dateRep'].iloc[-1] + pd.Timedelta(s_end - s_start, unit='days')"
2393 "cell_type": "code",
2394 "execution_count": null,
2396 "Collapsed": "false"
2400 "# data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['UK']), 'dateRep'].iloc[-1].strftime(\"%Y-%m-%d\")"
2404 "cell_type": "code",
2405 "execution_count": null,
2407 "Collapsed": "false"
2411 "# uk_covid_deaths * excess_deaths / reported_deaths"
2415 "cell_type": "code",
2416 "execution_count": null,
2418 "Collapsed": "false"
2422 "# uk_projection.deaths.sum() * excess_deaths / reported_deaths"
2426 "cell_type": "code",
2427 "execution_count": null,
2429 "Collapsed": "false"
2433 "# data_since_threshold.loc[(slice(None), 'FR'), :]\n",
2434 "# data_since_threshold[data_since_threshold.dateRep == '2020-05-18'].loc[(slice(None), 'FR'), :]"
2438 "cell_type": "markdown",
2440 "Collapsed": "false"
2443 "## School reopenings"
2447 "cell_type": "code",
2448 "execution_count": null,
2450 "Collapsed": "false"
2454 "school_reopenings = {\n",
2455 " 'ES': {'date': '2020-05-18'},\n",
2456 " 'FR': {'date': '2020-05-18'}, # some areas only\n",
2457 "# 'IT': {'date': '2020-09-01'},\n",
2458 " # 'IE': {'date': '2020-09-01'},\n",
2459 " 'DE': {'date': '2020-05-04'},\n",
2460 " 'UK': {'date': '2020-06-01'}\n",
2465 "cell_type": "code",
2466 "execution_count": null,
2468 "Collapsed": "false"
2472 "data_since_threshold[data_since_threshold.dateRep == '2020-05-04'].loc[(slice(None), ['DE']), :].first_valid_index()"
2476 "cell_type": "code",
2477 "execution_count": null,
2479 "Collapsed": "false"
2483 "data_since_threshold[data_since_threshold.dateRep == '2020-05-04'].loc[(slice(None), ['DE']), :].iloc[0].deaths_m7"
2487 "cell_type": "code",
2488 "execution_count": null,
2490 "Collapsed": "false"
2494 "for cID in school_reopenings:\n",
2495 " dst_in = data_since_threshold[data_since_threshold.dateRep == (school_reopenings[cID]['date'])].loc[(slice(None), [cID]), :]\n",
2496 " dst_i = dst_in.first_valid_index()\n",
2497 " dst_n = dst_in.iloc[0].deaths_m7\n",
2498 " school_reopenings[cID]['since_threshold'] = dst_i[0]\n",
2499 " school_reopenings[cID]['deaths_m7'] = dst_n\n",
2504 "cell_type": "code",
2505 "execution_count": null,
2507 "Collapsed": "false"
2511 "ax = deaths_m7[COUNTRIES_CORE].plot(figsize=(15, 9), title=\"Deaths per day, 7 day moving average\")\n",
2512 "# uk_projection.deaths_m7.plot(ax=ax)\n",
2513 "for c in COUNTRIES_CORE:\n",
2514 " lvi = deaths_m7[c].last_valid_index()\n",
2515 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = f\"{c}: {deaths_m7[c][lvi]:.0f}\")\n",
2516 " if c in school_reopenings:\n",
2517 " marker_col = [l for l in ax.lines if l.get_label() == c][0].get_color()\n",
2518 " ax.plot(school_reopenings[c]['since_threshold'], school_reopenings[c]['deaths_m7'], '*', \n",
2519 " markersize=18, markerfacecolor=marker_col, markeredgecolor=marker_col)\n",
2520 " ax.text(x = school_reopenings[c]['since_threshold'] + 1, y = school_reopenings[c]['deaths_m7'], \n",
2521 " s = f\"{school_reopenings[c]['date']}: {school_reopenings[c]['deaths_m7']:.0f}\")\n",
2522 "plt.savefig('school_reopenings.png')"
2526 "cell_type": "code",
2527 "execution_count": null,
2529 "Collapsed": "false"
2533 "# ax = deaths_m7[COUNTRIES_CORE].plot(figsize=(15, 9), title=\"Deaths per day, 7 day moving average\",\n",
2534 "# xlim=(46, 91), ylim=(0, 400))\n",
2535 "# # uk_projection.deaths_m7.plot(ax=ax)\n",
2536 "# for c in COUNTRIES_CORE:\n",
2537 "# lvi = deaths_m7[c].last_valid_index()\n",
2538 "# ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = f\"{c}: {deaths_m7[c][lvi]:.0f}\", fontsize=14)\n",
2539 "# if c in school_reopenings:\n",
2540 "# marker_col = [l for l in ax.lines if l.get_label() == c][0].get_color()\n",
2541 "# ax.plot(school_reopenings[c]['since_threshold'], school_reopenings[c]['deaths_m7'], '*', \n",
2542 "# markersize=18, markerfacecolor=marker_col, markeredgecolor=marker_col)\n",
2543 "# ax.text(x = school_reopenings[c]['since_threshold'] + 1, y = school_reopenings[c]['deaths_m7'], \n",
2544 "# s = f\"{school_reopenings[c]['date']}: {school_reopenings[c]['deaths_m7']:.0f}\",\n",
2546 "# plt.savefig('school_reopenings_detail.png')"
2550 "cell_type": "markdown",
2552 "Collapsed": "false"
2559 "cell_type": "code",
2560 "execution_count": null,
2562 "Collapsed": "false"
2566 "lockdown_dates = {\n",
2567 " 'ES': { 'part_start': {'date': '2020-03-14'}\n",
2568 " , 'full_start': {'date': '2020-03-15'}\n",
2569 " , 'part_finish': {'date': '2020-05-18'}\n",
2571 " 'FR': { 'part_start': {'date': '2020-03-13'}\n",
2572 " , 'full_start': {'date': '2020-03-17'}\n",
2573 " , 'part_finish': {'date': '2020-05-11'}\n",
2575 " 'IT': { 'part_start': {'date': '2020-03-08'}\n",
2576 " , 'full_start': {'date': '2020-03-10'}\n",
2577 " , 'part_finish': {'date': '2020-05-04'}\n",
2579 " 'DE': { #'part_start': {'date': '2020-03-13'}\n",
2580 " 'full_start': {'date': '2020-03-22'}\n",
2581 " , 'part_finish': {'date': '2020-05-06'}\n",
2583 " 'UK': { 'part_start': {'date': '2020-03-23'}\n",
2584 " , 'full_start': {'date': '2020-03-23'}\n",
2585 " , 'part_finish': {'date': '2020-05-31'}\n",
2587 " 'IE': { #'part_start': {'date': '2020-03-12'}\n",
2588 " 'full_start': {'date': '2020-03-27'}\n",
2589 " , 'part_finish': {'date': '2020-05-18'}\n",
2595 "cell_type": "code",
2596 "execution_count": null,
2598 "Collapsed": "false"
2602 "for cID in lockdown_dates:\n",
2603 " for phase in lockdown_dates[cID]:\n",
2604 " dst_in = data_since_threshold[data_since_threshold.dateRep == (lockdown_dates[cID][phase]['date'])].loc[(slice(None), [cID]), :]\n",
2605 " dst_i = dst_in.first_valid_index()\n",
2606 " dst_n = dst_in.iloc[0].deaths_m7\n",
2607 " dst_c = dst_in.iloc[0].cases_m7\n",
2608 " lockdown_dates[cID][phase]['since_threshold'] = dst_i[0]\n",
2609 " lockdown_dates[cID][phase]['deaths_m7'] = dst_n\n",
2610 " lockdown_dates[cID][phase]['cases_m7'] = dst_c\n",
2616 "cell_type": "code",
2617 "execution_count": null,
2619 "Collapsed": "false"
2623 "ax = deaths_m7[COUNTRIES_CORE].plot(figsize=(15, 9), title=\"Deaths per day, 7 day moving averagee, with lockdown dates\")\n",
2624 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
2625 "# uk_projection.deaths_m7.plot(ax=ax)\n",
2626 "for c in COUNTRIES_CORE:\n",
2627 " lvi = deaths_m7[c].last_valid_index()\n",
2629 " ax.text(x = lvi + 1, y = deaths_m7[c][lvi], s = f\"{c}: {deaths_m7[c][lvi]:.0f}\")\n",
2630 " if c in lockdown_dates:\n",
2631 " for phase in lockdown_dates[c]:\n",
2632 " marker_col = [l for l in ax.lines if l.get_label() == c][0].get_color()\n",
2633 " ax.plot(lockdown_dates[c][phase]['since_threshold'], lockdown_dates[c][phase]['deaths_m7'], '*',\n",
2634 " markersize=18, markerfacecolor=marker_col, markeredgecolor=marker_col)\n",
2635 " if 'start' not in phase:\n",
2636 " ax.text(x = lockdown_dates[c][phase]['since_threshold'] + 1, y = lockdown_dates[c][phase]['deaths_m7'], \n",
2637 " s = f\"{lockdown_dates[c][phase]['date']}: {lockdown_dates[c][phase]['deaths_m7']:.0f}\")\n",
2638 "# plt.savefig('school_reopenings.png')"
2642 "cell_type": "code",
2643 "execution_count": null,
2645 "Collapsed": "false"
2649 "ax = cases_m7.iloc[-50:][COUNTRIES_CORE].plot(figsize=(15, 9), title=\"Cases per day, 7 day moving average, with lockdown dates\") #, ylim=(-10, 1500))\n",
2650 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
2651 "# uk_projection.deaths_m7.plot(ax=ax)\n",
2652 "for c in COUNTRIES_CORE:\n",
2653 " lvi = cases_m7[c].last_valid_index()\n",
2654 "# if c != 'UK':\n",
2655 " ax.text(x = lvi + 1, y = cases_m7[c][lvi], s = f\"{c}: {cases_m7[c][lvi]:.0f}\")\n"
2659 "cell_type": "code",
2660 "execution_count": null,
2662 "Collapsed": "false"
2666 "ax = cases_m7[COUNTRIES_CORE].plot(figsize=(15, 9), title=\"Cases per day, 7 day moving average, with lockdown dates\")\n",
2667 "ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
2668 "# uk_projection.deaths_m7.plot(ax=ax)\n",
2669 "for c in COUNTRIES_CORE:\n",
2670 " lvi = cases_m7[c].last_valid_index()\n",
2671 "# if c != 'UK':\n",
2672 " ax.text(x = lvi + 1, y = cases_m7[c][lvi], s = f\"{c}: {cases_m7[c][lvi]:.0f}\")\n",
2673 " if c in lockdown_dates:\n",
2674 " for phase in lockdown_dates[c]:\n",
2675 " marker_col = [l for l in ax.lines if l.get_label() == c][0].get_color()\n",
2676 " if 'start' in phase:\n",
2677 " marker_shape = '^'\n",
2679 " marker_shape = 'v'\n",
2680 " ax.plot(lockdown_dates[c][phase]['since_threshold'], lockdown_dates[c][phase]['cases_m7'], \n",
2682 " markersize=18, markerfacecolor=marker_col, markeredgecolor=marker_col)\n",
2683 " if 'start' not in phase:\n",
2684 " ax.text(x = lockdown_dates[c][phase]['since_threshold'] + 1, y = lockdown_dates[c][phase]['cases_m7'], \n",
2685 " s = f\"{lockdown_dates[c][phase]['date']}: {lockdown_dates[c][phase]['cases_m7']:.0f}\")\n",
2686 "# plt.savefig('cases_per_day_with_lockdown.png')"
2690 "cell_type": "code",
2691 "execution_count": null,
2693 "Collapsed": "false"
2697 "plot_start_date = '2020-03-01'\n",
2698 "ax = cases_by_date_m7.loc[plot_start_date:, COUNTRIES_CORE].plot(figsize=(15, 9), title=\"Cases per day, 7 day moving average, with lockdown dates\")\n",
2699 "ax.set_xlabel(f\"Date\")\n",
2700 "ax.set_ylabel(\"Number of cases\")\n",
2701 "# uk_projection.deaths_m7.plot(ax=ax)\n",
2702 "for c in COUNTRIES_CORE:\n",
2703 " lvi = cases_by_date_m7[c].last_valid_index()\n",
2704 "# if c != 'UK':\n",
2705 " ax.text(x = lvi + pd.Timedelta(days=1), y = cases_by_date_m7[c][lvi], s = f\"{c}: {cases_by_date_m7[c][lvi]:.0f}\")\n",
2706 " if c in lockdown_dates:\n",
2707 " for phase in lockdown_dates[c]:\n",
2708 " marker_col = [l for l in ax.lines if l.get_label() == c][0].get_color()\n",
2709 " if 'start' in phase:\n",
2710 " marker_shape = '^'\n",
2712 " marker_shape = 'v'\n",
2713 " marker_x_pos = ax.get_xlim()[0] + mpl.dates.date2num(pd.to_datetime(lockdown_dates[c][phase]['date'])) - mpl.dates.date2num(pd.to_datetime(plot_start_date))\n",
2714 " ax.plot(marker_x_pos, lockdown_dates[c][phase]['cases_m7'], \n",
2716 " markersize=18, markerfacecolor=marker_col, markeredgecolor=marker_col)\n",
2717 " if 'start' not in phase:\n",
2718 " ax.text(x = marker_x_pos + 3, y = lockdown_dates[c][phase]['cases_m7'], \n",
2719 " s = f\"{lockdown_dates[c][phase]['date']}: {lockdown_dates[c][phase]['cases_m7']:.0f}\")\n",
2720 "plt.savefig('cases_per_day_with_lockdown.png')"
2724 "cell_type": "code",
2725 "execution_count": null,
2727 "Collapsed": "false"
2731 "ax = cases_m7[COUNTRIES_CORE].plot(figsize=(10, 6), title=\"Cases per day, 7 day moving average\")\n",
2732 "for c in COUNTRIES_CORE:\n",
2733 " lvi = cases_m7[c].last_valid_index()\n",
2734 " ax.text(x = lvi + 1, y = cases_m7[c][lvi], s = c)\n",
2735 "plt.savefig('covid_cases_per_day-core.png') "
2739 "cell_type": "code",
2740 "execution_count": null,
2742 "Collapsed": "false"
2746 "ax = deaths_m7[COUNTRIES_CORE].plot(figsize=(15, 9), title=\"Deaths per day, 7 day moving average\",\n",
2747 " xlim=(0, 15), \n",
2750 "# uk_projection.deaths_m7.plot(ax=ax)\n",
2751 "for c in COUNTRIES_CORE:\n",
2752 " lvi = deaths_m7[c].last_valid_index()\n",
2753 " if c in lockdown_dates:\n",
2754 " for phase in lockdown_dates[c]:\n",
2755 " if 'start' in phase:\n",
2756 " print(c, phase)\n",
2757 " marker_col = [l for l in ax.lines if l.get_label() == c][0].get_color()\n",
2758 " ax.plot(lockdown_dates[c][phase]['since_threshold'], lockdown_dates[c][phase]['deaths_m7'], '*', \n",
2759 " markersize=18, markerfacecolor=marker_col, markeredgecolor=marker_col)\n",
2760 " ax.text(x = lockdown_dates[c][phase]['since_threshold'] + 0.3, y = lockdown_dates[c][phase]['deaths_m7'], \n",
2761 " s = f\"{lockdown_dates[c][phase]['date']}: {lockdown_dates[c][phase]['deaths_m7']:.0f}\")\n",
2762 "# plt.savefig('school_reopenings.png')"
2766 "cell_type": "code",
2767 "execution_count": null,
2769 "Collapsed": "false"
2775 "cell_type": "code",
2776 "execution_count": null,
2778 "Collapsed": "false"
2784 "cell_type": "markdown",
2786 "Collapsed": "false"
2789 "# Write results to summary file"
2793 "cell_type": "code",
2794 "execution_count": null,
2796 "Collapsed": "false"
2800 "with open('covid_summary.md', 'w') as f:\n",
2801 " f.write('% Covid death data summary\\n')\n",
2802 " f.write('% Neil Smith\\n')\n",
2803 " f.write(f'% Created on {datetime.datetime.now().strftime(\"%Y-%m-%d\")}\\n')\n",
2804 " f.write('\\n')\n",
2806 " last_uk_date = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['UK']), 'dateRep'].iloc[-1]\n",
2807 " f.write(f'> Last UK data from {last_uk_date.strftime(\"%Y-%m-%d\")}\\n')\n",
2812 "cell_type": "code",
2813 "execution_count": null,
2815 "Collapsed": "false"
2819 "with open('covid_summary.md', 'a') as f:\n",
2820 " f.write('## Headlines\\n')\n",
2821 " f.write('\\n')\n",
2822 " f.write('| []() | |\\n')\n",
2823 " f.write('|:---|---:|\\n')\n",
2824 " f.write(f'| Deaths reported so far | {uk_covid_deaths} | \\n')\n",
2825 " f.write(f'| Total Covid deaths to date (estimated) | {uk_deaths_to_date:.0f} |\\n')\n",
2826 " projection_date = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['IT']), 'dateRep'].iloc[-1] + pd.Timedelta(s_end - s_start, unit='days')\n",
2827 "# f.write(f'| Projected total deaths up to {projection_date.strftime(\"%Y-%m-%d\")} | {deaths_actual_projected_scaled:.0f} | \\n')\n",
2832 "cell_type": "code",
2833 "execution_count": null,
2835 "Collapsed": "false"
2839 "with open('covid_summary.md', 'a') as f:\n",
2840 " f.write('## Total deaths\\n')\n",
2841 "# f.write(f'Time based on days since {DEATH_COUNT_THRESHOLD} deaths\\n')\n",
2842 " f.write('\\n')\n",
2843 " f.write('![Total deaths](covid_deaths_total_linear.png)\\n')\n",
2844 " f.write('\\n')\n",
2845 " f.write('| Country ID | Country name | Total deaths |\\n')\n",
2846 " f.write('|:-----------|:-------------|-------------:|\\n')\n",
2847 " for c in sorted(COUNTRIES_CORE):\n",
2848 " lvi = deaths_by_date[c].last_valid_index()\n",
2849 " f.write(f'| {c} | {countries.loc[c].countriesAndTerritories} | {int(deaths_by_date[c][lvi])} |\\n')\n",
2854 "cell_type": "code",
2855 "execution_count": null,
2857 "Collapsed": "false"
2861 "with open('covid_summary.md', 'a') as f:\n",
2862 " f.write('## All-causes deaths, UK\\n')\n",
2863 " f.write('\\n')\n",
2864 " f.write('![All-causes deaths](deaths-radar.png)\\n')\n",
2865 " f.write('\\n')\n",
2866 " f.write('### True deaths\\n')\n",
2867 " f.write('\\n')\n",
2868 " f.write(f'The number of deaths reported in official statistics, {uk_covid_deaths}, is an underestimate '\n",
2869 " 'of the true number of Covid deaths.\\n'\n",
2870 " 'This is especially true early in the pandemic, approximately March to May 2020.\\n')\n",
2871 " f.write('We can get a better understanding of the impact of Covid by looking at the number of deaths, '\n",
2872 " 'over and above what would be expected at each week of the year.\\n')\n",
2873 " f.write(f'The ONS (and other bodies in Scotland and Northern Ireland) have released data on the number of deaths '\n",
2874 " f'up to {pd.to_datetime(excess_deaths_data[\"end_date\"]).strftime(\"%d %B %Y\")}.\\n\\n')\n",
2875 " f.write('If, for each of those weeks, I take the largest of the excess deaths or the reported Covid deaths, ')\n",
2876 " f.write(f'I estimate there have been **{uk_deaths_to_date}** total deaths so far.\\n')\n",
2881 "cell_type": "code",
2882 "execution_count": null,
2884 "Collapsed": "false"
2888 "# with open('covid_summary.md', 'a') as f:\n",
2889 "# f.write(f'In that period, the UK reported {ons_reported_deaths} Covid deaths.\\n')\n",
2890 "# f.write(f'In the last three weeks for which excess deaths have been reported, the excess deaths have been {excess_death_accuracy:.3f} higher than the Covid-reported deaths.\\n')\n",
2891 "# # f.write(f'That means the actual number of Covid death is about {excess_deaths / reported_deaths:.2f} times higher than the reported figures.\\n')\n",
2892 "# f.write('\\n')\n",
2893 "# f.write(f'The UK has reported {uk_covid_deaths} deaths so far.\\n')\n",
2894 "# f.write(f'Using the scaling factor above (for Covid-19 deaths after the ONS figures), I infer that there have been **{uk_deaths_to_date:.0f}** total deaths so far.\\n')\n",
2899 "cell_type": "code",
2900 "execution_count": null,
2902 "Collapsed": "false"
2906 "with open('covid_summary.md', 'a') as f:\n",
2907 " f.write('## Deaths per day\\n')\n",
2908 " f.write(f'Based on a 7-day moving average\\n')\n",
2909 " f.write('\\n')\n",
2910 " f.write('![Deaths per day](covid_deaths_per_day_7.png)\\n')\n",
2911 " f.write('\\n')\n",
2912 " f.write('![Deaths per day, last 30 days](deaths_by_date_last_30_days.png)\\n')\n",
2917 "cell_type": "code",
2918 "execution_count": null,
2920 "Collapsed": "false"
2924 "s_end - s_start - 1"
2928 "cell_type": "code",
2929 "execution_count": null,
2931 "Collapsed": "false"
2935 "with open('covid_summary.md', 'a') as f:\n",
2936 " f.write('## Projected deaths\\n')\n",
2937 " f.write(\"Previously, I was using Italy's deaths data to predict the UK's deaths data. \"\n",
2938 " \"This worked when both countries' trends of deaths were falling or constant, \"\n",
2939 " \"as they were until September.\\n\")\n",
2940 " f.write(\"\\n\")\n",
2941 " f.write(\"As of mid-September, with cases rising in both countries at around the same time, \"\n",
2942 " \"I can't use Italian data to predict the UK's future deaths.\\n\")\n",
2943 " f.write(\"\\n\")\n",
2944 "# f.write(f\"The UK's daily deaths data is very similar to Italy's.\\n\")\n",
2945 "# f.write(f'If I use the Italian data for the next {s_end - s_start - 1} days (from {s_start_date.strftime(\"%d %B %Y\")} onwards),')\n",
2946 "# f.write(f' the UK will report {uk_projection.deaths.sum()} deaths on day {uk_end} of the epidemic.\\n')\n",
2947 "# f.write('\\n')\n",
2948 "# f.write('Using the excess deaths scaling from above, that will translate into ')\n",
2949 "# f.write(f'**{deaths_actual_projected_scaled:.0f}** Covid deaths total.\\n')\n",
2954 "cell_type": "code",
2955 "execution_count": null,
2957 "Collapsed": "false"
2961 "with open('covid_summary.md', 'a') as f:\n",
2962 " f.write('## Deaths doubling times\\n')\n",
2963 " f.write(f'Based on a 7-day moving average\\n')\n",
2964 " f.write('\\n')\n",
2965 " f.write('![Deaths doubling times](covid_doubling_times_7.png)\\n')\n",
2970 "cell_type": "code",
2971 "execution_count": null,
2973 "Collapsed": "false"
2977 "with open('covid_summary.md', 'a') as f:\n",
2978 " f.write('\\n')\n",
2979 " f.write('## Cases per day and lockdown dates\\n')\n",
2980 " f.write(f'Based on a 7-day moving average\\n')\n",
2981 " f.write('\\n')\n",
2982 " f.write('![Cases per day](cases_per_day_with_lockdown.png)\\n')\n",
2987 "cell_type": "code",
2988 "execution_count": null,
2990 "Collapsed": "false"
2994 "with open('covid_summary.md', 'a') as f:\n",
2995 " f.write('| Country ID | Country name | Most recent daily cases | Most recent daily deaths |\\n')\n",
2996 " f.write('|:-----------|:-------------|------------------------:|-------------------------:|\\n')\n",
2997 " for c in sorted(COUNTRIES_CORE):\n",
2998 " lvic = cases_m7[c].last_valid_index()\n",
2999 " lvid = deaths_m7[c].last_valid_index()\n",
3000 " f.write(f'| {c} | {countries.loc[c].countriesAndTerritories} | {cases_m7[c][lvic]:.0f} | {deaths_m7[c][lvid]:.0f} | \\n')\n",
3001 " f.write('\\n')\n",
3002 " f.write('(Figures are 7-day averages)\\n')\n",
3007 "cell_type": "code",
3008 "execution_count": null,
3010 "Collapsed": "false"
3014 "with open('hospital_normalisation_date.json') as f:\n",
3015 " hospital_normalisation_date_data = json.load(f)"
3019 "cell_type": "code",
3020 "execution_count": null,
3022 "Collapsed": "false"
3026 "with open('covid_summary.md', 'a') as f:\n",
3027 " f.write('## Hospital care\\n')\n",
3028 " f.write(f'Based on a 7-day moving average\\n')\n",
3029 " f.write('\\n')\n",
3030 " f.write('![Cases, admissions, deaths](cases_admissions_deaths.png)\\n')\n",
3031 " f.write('\\n')\n",
3032 "# f.write('Admissions are shifted by 10 days, deaths by 25 days. '\n",
3033 "# 'This reflects the typical timescales of infection: '\n",
3034 "# 'patients are admitted 10 days after onset of symptoms, '\n",
3035 "# 'and die 15 days after admission.\\n')\n",
3036 "# f.write('\\n')\n",
3037 "# f.write('Plotting this data with offsets shows more clearly '\n",
3038 "# 'the relative changes in these three metrics.\\n')\n",
3039 " f.write('Due to the large scale differences between the three '\n",
3040 " 'measures, they are all normalised to show changes ')\n",
3041 " f.write(f'since {pd.to_datetime(hospital_normalisation_date_data[\"hospital_normalisation_date\"]).strftime(\"%d %B %Y\")}.\\n')\n",
3046 "cell_type": "code",
3047 "execution_count": null,
3049 "Collapsed": "false"
3053 "with open('covid_summary.md', 'a') as f:\n",
3054 " f.write('## Testing effectiveness\\n')\n",
3055 " f.write('\\n')\n",
3056 " f.write('A question about testing is whether more detected cases is a result of more tests being '\n",
3057 " 'done or is because the number of cases is increasing. One way of telling the differeence '\n",
3058 " 'is by looking at the fraction of tests that are positive.\\n')\n",
3059 " f.write('\\n')\n",
3060 " f.write('![Positive tests and cases](tests_and_cases.png)\\n')\n",
3061 " f.write('\\n')\n",
3062 " f.write('Numbers of positive tests and cases, '\n",
3063 " '7-day moving average.\\n'\n",
3064 " 'Note the different y-axes\\n')\n",
3065 " f.write('\\n') \n",
3066 " f.write('![Fraction of tests with positive result](fraction_positive_tests.png)\\n')\n",
3067 " f.write('\\n')\n",
3068 " f.write('Fraction of tests with a positive result, both daily figures and '\n",
3069 " '7-day moving average.\\n')\n",
3070 " f.write('\\n') \n",
3071 " f.write('\\n')\n",
3072 " f.write('![Tests against fraction positive, trajectory](fraction_positive_tests_vs_tests.png)\\n')\n",
3073 " f.write('\\n')\n",
3074 " f.write('The trajectory of tests done vs fraction positive tests.\\n')\n",
3075 " f.write('\\n')\n",
3076 " f.write('Points higher indicate more tests; points to the right indicate more positive tests.'\n",
3077 " 'More tests being done with the same infection prevelance will move the point up '\n",
3078 " 'and to the left.\\n')\n",
3079 " f.write('\\n')\n",
3080 " f.write('\\n')\n",
3081 " f.write('![Tests against fraction positive, trajectory](tests_vs_fraction_positive_animation.png)\\n')\n",
3086 "cell_type": "code",
3087 "execution_count": null,
3089 "Collapsed": "false"
3095 "cell_type": "code",
3096 "execution_count": null,
3098 "Collapsed": "false"
3102 "with open('covid_summary.md', 'a') as f:\n",
3103 " f.write('# Data sources\\n')\n",
3104 " f.write('\\n')\n",
3105 " f.write('> Covid data from [European Centre for Disease Prevention and Control](https://www.ecdc.europa.eu/en/publications-data/download-todays-data-geographic-distribution-covid-19-cases-worldwide)\\n')\n",
3106 " f.write('\\n') \n",
3107 " f.write(\"\"\"> Population data from:\n",
3109 "* [Office of National Statistics](https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/deaths/datasets/weeklyprovisionalfiguresondeathsregisteredinenglandandwales) (Endland and Wales) Weeks start on a Saturday.\n",
3110 "* [Northern Ireland Statistics and Research Agency](https://www.nisra.gov.uk/publications/weekly-deaths) (Northern Ireland). Weeks start on a Saturday. Note that the week numbers don't match the England and Wales data.\n",
3111 "* [National Records of Scotland](https://www.nrscotland.gov.uk/statistics-and-data/statistics/statistics-by-theme/vital-events/general-publications/weekly-and-monthly-data-on-births-and-deaths/weekly-data-on-births-and-deaths) (Scotland). Note that Scotland uses ISO8601 week numbers, which start on a Monday.\"\"\")\n",
3113 " f.write('\\n\\n')\n",
3114 " f.write('> [Source code available](https://git.njae.me.uk/?p=covid19.git;a=tree)\\n')\n",
3115 " f.write('\\n') \n"
3119 "cell_type": "code",
3120 "execution_count": null,
3122 "Collapsed": "false"
3126 "!pandoc --toc -s covid_summary.md > covid_summary.html"
3130 "cell_type": "code",
3131 "execution_count": null,
3133 "Collapsed": "false"
3137 "!scp covid_summary.html neil@ogedei:/var/www/scripts.njae.me.uk/covid/index.html\n",
3138 "!scp covid_deaths_total_linear.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3139 "!scp deaths-radar.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3140 "!scp covid_deaths_per_day_7.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3141 "!scp covid_doubling_times_7.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3142 "!scp cases_per_day_with_lockdown.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3143 "!scp cases_admissions_deaths.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3144 "!scp fraction_positive_tests.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/ \n",
3145 "!scp tests_and_cases.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3146 "!scp deaths_by_date_last_30_days.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3147 "!scp fraction_positive_tests_vs_tests.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3148 "!scp tests_vs_fraction_positive_animation.png neil@ogedei:/var/www/scripts.njae.me.uk/covid/ "
3152 "cell_type": "code",
3153 "execution_count": null,
3155 "Collapsed": "false"
3159 "with open('uk_covid_deaths.js', 'w') as f:\n",
3160 " f.write(f\"document.write('{uk_covid_deaths}');\")\n",
3162 "with open('estimated_total_deaths.js', 'w') as f:\n",
3163 " f.write(f\"document.write('{uk_deaths_to_date:.0f}');\")\n",
3165 "# with open('projection_date.js', 'w') as f:\n",
3166 "# f.write(f\"document.write(\\'{projection_date.strftime('%d %B %Y')}\\');\")\n",
3168 "# with open('projected_deaths.js', 'w') as f:\n",
3169 "# f.write(f\"document.write('{uk_projection.deaths.sum():.0f}');\")\n",
3171 "# with open('projected_excess_deaths.js', 'w') as f:\n",
3172 "# f.write(f\"document.write('{deaths_actual_projected_scaled:.0f}');\")\n",
3174 "edut = pd.to_datetime(excess_deaths_data[\"end_date\"]).strftime('%d %B %Y')\n",
3175 "with open('excess_deaths_upto.js', 'w') as f:\n",
3176 " f.write(f\"document.write('{edut}');\")\n",
3178 "# with open('excess_deaths.js', 'w') as f:\n",
3179 "# f.write(f\"document.write('{excess_deaths:.0f}');\")\n",
3181 "# with open('reported_deaths.js', 'w') as f:\n",
3182 "# f.write(f\"document.write('{ons_reported_deaths:.0f}');\")\n",
3184 "# with open('scaling_factor.js', 'w') as f:\n",
3185 "# f.write(f\"document.write('{excess_death_accuracy:.2f}');\") \n",
3187 "# with open('projection_length.js', 'w') as f:\n",
3188 "# f.write(f\"document.write('{s_end - s_start - 1}');\")\n",
3190 "# with open('s_end.js', 'w') as f:\n",
3191 "# f.write(f\"document.write('{s_end}');\")\n",
3193 "# s_start_date_str = s_start_date.strftime(\"%d %B %Y\")\n",
3194 "# with open('s_start_date.js', 'w') as f:\n",
3195 "# f.write(f\"document.write('{s_start_date_str}');\")\n",
3197 "# with open('uk_end.js', 'w') as f:\n",
3198 "# f.write(f\"document.write('{uk_end}');\")\n",
3200 "with open('last_uk_date.js', 'w') as f:\n",
3201 " f.write(f\"document.write('{pd.to_datetime(last_uk_date).strftime('%d %B %Y')}');\")"
3205 "cell_type": "code",
3206 "execution_count": null,
3208 "Collapsed": "false"
3212 "# pd.to_datetime(excess_deaths_upto).strftime('%d %B %Y')"
3216 "cell_type": "code",
3217 "execution_count": null,
3219 "Collapsed": "false"
3223 "!scp uk_covid_deaths.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3224 "!scp estimated_total_deaths.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3225 "# !scp projection_date.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3226 "# !scp projected_deaths.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3227 "# !scp projected_excess_deaths.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3228 "!scp excess_deaths_upto.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3229 "# !scp excess_deaths.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3230 "# !scp reported_deaths.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3231 "# !scp scaling_factor.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3232 "# !scp projection_length.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3233 "# !scp s_end.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3234 "# !scp s_start_date.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3235 "# !scp uk_end.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3236 "!scp last_uk_date.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/\n",
3237 "!scp hospital_normalisation_date.js neil@ogedei:/var/www/scripts.njae.me.uk/covid/"
3241 "cell_type": "code",
3242 "execution_count": null,
3244 "Collapsed": "false"
3248 "data_by_date.loc['UK'].to_csv('data_by_day_uk.csv', header=True, index=True)\n",
3249 "data_by_date.loc['BE'].to_csv('data_by_day_be.csv', header=True, index=True)"
3253 "cell_type": "code",
3254 "execution_count": null,
3256 "Collapsed": "false"
3260 "ukd = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['UK']), ['deaths', 'deaths_m7']].droplevel(1)\n",
3261 "ax = ukd.deaths.plot.bar(figsize=(12, 8))\n",
3262 "ukd.deaths_m7.plot.line(ax=ax, color='red')\n",
3263 "# ax = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['UK']), 'deaths_m7'].plot.line(figsize=(12, 8), color='red')\n",
3264 "# ax = data_since_threshold.replace([np.inf, -np.inf], np.nan).loc[(slice(None), ['UK']), 'deaths'].plot.bar(ax=ax)\n",
3265 "ax.set_xticks(range(0, 120, 20))"
3269 "cell_type": "code",
3270 "execution_count": null,
3272 "Collapsed": "false"
3276 "ukdd = data_by_date.loc['UK'].iloc[-30:]\n",
3277 "ax = ukdd.deaths_m7.plot.line(figsize=(12, 8), color='red')\n",
3278 "# ukdd.deaths.plot.bar(ax=ax)\n",
3279 "ax.bar(ukdd.index, ukdd.deaths)"
3283 "cell_type": "code",
3284 "execution_count": null,
3286 "Collapsed": "false"
3294 "cell_type": "code",
3295 "execution_count": null,
3297 "Collapsed": "false"
3301 "np.arange(0, 130, 20)"
3305 "cell_type": "code",
3306 "execution_count": null,
3308 "Collapsed": "false"
3312 "data_by_date.loc['UK']"
3316 "cell_type": "code",
3317 "execution_count": null,
3319 "Collapsed": "false"
3323 "data_by_date.loc['UK'].plot(x='deaths_culm', y='deaths', logx=True, logy=True)"
3327 "cell_type": "code",
3328 "execution_count": null,
3330 "Collapsed": "false"
3334 "data_by_date.loc['UK'].plot(x='cases_culm', y='cases')"
3338 "cell_type": "code",
3339 "execution_count": null,
3341 "Collapsed": "false"
3345 "ukdbd = data_by_date.loc['UK'].copy()\n",
3346 "ukdbd['deaths_m7'] = ukdbd.deaths.transform(lambda x: x.rolling(7, 1).mean())\n",
3347 "ukdbd['cases_m7'] = ukdbd.cases.transform(lambda x: x.rolling(7, 1).mean())\n",
3352 "cell_type": "code",
3353 "execution_count": null,
3355 "Collapsed": "false"
3359 "ukdbd.plot(x='deaths_culm', y='deaths_m7', logx=True, logy=True)"
3363 "cell_type": "code",
3364 "execution_count": null,
3366 "Collapsed": "false"
3370 "fig, ax = plt.subplots(figsize=(12, 8))\n",
3372 "for c in COUNTRIES_CORE:\n",
3373 " if data_since_threshold.loc[(slice(None), c), 'deaths_culm'].max() > xmax:\n",
3374 " xmax = data_since_threshold.loc[(slice(None), c), 'deaths_culm'].max()\n",
3375 " data_since_threshold.loc[(slice(None), c), :].plot(x='deaths_culm', y='deaths_m7', logx=True, logy=True, xlim=(10, xmax * 1.1), label=c, ax=ax)"
3379 "cell_type": "code",
3380 "execution_count": null,
3382 "Collapsed": "false"
3386 "data_since_threshold.loc[(slice(None), 'UK'), 'deaths_culm'].max()"
3390 "cell_type": "code",
3391 "execution_count": null,
3393 "Collapsed": "false"
3397 "countries.continentExp.unique()"
3401 "cell_type": "code",
3402 "execution_count": null,
3404 "Collapsed": "false"
3408 "countries.loc['KW']"
3412 "cell_type": "code",
3413 "execution_count": null,
3415 "Collapsed": "false"
3419 "data_by_date.groupby(level=0)['deaths'].shift(-25)"
3423 "cell_type": "code",
3424 "execution_count": null,
3426 "Collapsed": "false"
3430 "offset_data = data_by_date.loc[:, ['cases']]\n",
3431 "offset_data['deaths'] = data_by_date.groupby(level=0)['deaths'].shift(-25)\n",
3432 "offset_data['cases_m7'] = offset_data.groupby(level=0)['cases'].transform(lambda x: x.rolling(7, 1).mean())\n",
3433 "offset_data['deaths_m7'] = offset_data['deaths'].dropna().groupby(level=0).transform(lambda x: x.rolling(7, 1).mean())\n",
3434 "offset_data['deaths_per_case'] = offset_data.deaths_m7 / offset_data.cases_m7\n",
3439 "cell_type": "code",
3440 "execution_count": null,
3442 "Collapsed": "false"
3450 "cell_type": "code",
3451 "execution_count": null,
3453 "Collapsed": "false"
3457 "offset_deaths_m7 = (offset_data.loc[COUNTRIES_ALL, ['deaths_m7']]\n",
3458 " .unstack().sort_index().xs('deaths_m7', axis=1, drop_level=True)).T.sort_index()\n",
3463 "cell_type": "code",
3464 "execution_count": null,
3466 "Collapsed": "false"
3470 "offset_deaths_m7['UK']"
3474 "cell_type": "code",
3475 "execution_count": null,
3477 "Collapsed": "false"
3481 "data_since_threshold.loc[(slice(None), 'UK'), :].tail()"
3485 "cell_type": "code",
3486 "execution_count": null,
3488 "Collapsed": "false"
3492 "countries.loc['PT']"
3496 "cell_type": "code",
3497 "execution_count": null,
3499 "Collapsed": "false"
3503 "ax = cases_by_date_m7.iloc[-50:][COUNTRIES_FRIENDS].plot(figsize=(15, 9), title=\"Cases per day, 7 day moving average\")#, ylim=(-10, 1500))\n",
3504 "# ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
3505 "# uk_projection.deaths_m7.plot(ax=ax)\n",
3506 "for c in COUNTRIES_FRIENDS:\n",
3507 " lvi = cases_by_date_m7[c].last_valid_index()\n",
3508 " ax.text(x = lvi + pd.Timedelta(days=1), y = cases_by_date_m7[c][lvi], s = f\"{c}: {cases_by_date_m7[c][lvi]:.0f}\")\n"
3512 "cell_type": "code",
3513 "execution_count": null,
3515 "Collapsed": "false"
3519 "ax = deaths_by_date_m7.iloc[-50:][COUNTRIES_FRIENDS].plot(figsize=(15, 9), title=\"Deaths per day, 7 day moving average\")#, ylim=(-10, 100))\n",
3520 "# ax.set_xlabel(f\"Days since {DEATH_COUNT_THRESHOLD} deaths\")\n",
3521 "# uk_projection.deaths_m7.plot(ax=ax)\n",
3522 "for c in COUNTRIES_FRIENDS:\n",
3523 " lvi = deaths_by_date_m7[c].last_valid_index()\n",
3524 "# if c != 'ES':\n",
3525 " ax.text(x = lvi + pd.Timedelta(days=1), y = deaths_by_date_m7[c][lvi], s = f\"{c}: {deaths_by_date_m7[c][lvi]:.0f}\")"
3529 "cell_type": "code",
3530 "execution_count": null,
3532 "Collapsed": "false"
3540 "formats": "ipynb,md"
3543 "display_name": "Python 3",
3544 "language": "python",
3548 "codemirror_mode": {
3552 "file_extension": ".py",
3553 "mimetype": "text/x-python",
3555 "nbconvert_exporter": "python",
3556 "pygments_lexer": "ipython3",