forked from RainerHeintzmann/StateModeling
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fetch_data.py
212 lines (187 loc) · 10.7 KB
/
fetch_data.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# This code is from the HackCorona project and was written largely by Manuel Lang
import pandas as pd
from datetime import date, timedelta, datetime
from dotenv import load_dotenv
import json
import urllib
import urllib.request
from configparser import ConfigParser
import requests
import os
import numpy as np
# von : https://www.arcgis.com/home/item.html?id=dd4580c810204019a7b8eb3e0b329dd6
# Beschreibung der Daten des RKI Covid-19-Dashboards (https://corona.rki.de)
#
# Dem Dashboard liegen aggregierte Daten der gemäß IfSG von den Gesundheitsämtern an das RKI übermittelten Covid-19-Fälle zu Grunde
# Mit den Daten wird der tagesaktuelle Stand (00:00 Uhr) abgebildet und es werden die Veränderungen bei den Fällen und Todesfällen zum Vortag dargstellt
# In der Datenquelle sind folgende Parameter enthalten:
# IdBundesland: Id des Bundeslands des Falles mit 1=Schleswig-Holstein bis 16=Thüringen
# Bundesland: Name des Bundeslanes
# Landkreis ID: Id des Landkreises des Falles in der üblichen Kodierung 1001 bis 16077=LK Altenburger Land
# Landkreis: Name des Landkreises
# Altersgruppe: Altersgruppe des Falles aus den 6 Gruppe 0-4, 5-14, 15-34, 35-59, 60-79, 80+ sowie unbekannt
# Geschlecht: Geschlecht des Falles M0männlich, W=weiblich und unbekannt
# AnzahlFall: Anzahl der Fälle in der entsprechenden Gruppe
# AnzahlTodesfall: Anzahl der Todesfälle in der entsprechenden Gruppe
# Meldedatum: Datum, wann der Fall dem Gesundheitsamt bekannt geworden ist
# Datenstand: Datum, wann der Datensatz zuletzt aktualisiert worden ist
# NeuerFall:
# 0: Fall ist in der Publikation für den aktuellen Tag und in der für den Vortag enthalten
# 1: Fall ist nur in der aktuellen Publikation enthalten
# -1: Fall ist nur in der Publikation des Vortags enthalten
# damit ergibt sich: Anzahl Fälle der aktuellen Publikation als Summe(AnzahlFall), wenn NeuerFall in (0,1); Delta zum Vortag als Summe(AnzahlFall) wenn NeuerFall in (-1,1)
# NeuerTodesfall:
# 0: Fall ist in der Publikation für den aktuellen Tag und in der für den Vortag jeweils ein Todesfall
# 1: Fall ist in der aktuellen Publikation ein Todesfall, nicht jedoch in der Publikation des Vortages
# -1: Fall ist in der aktuellen Publikation kein Todesfall, jedoch war er in der Publikation des Vortags ein Todesfall
# -9: Fall ist weder in der aktuellen Publikation noch in der des Vortages ein Todesfall
# damit ergibt sich: Anzahl Todesfälle der aktuellen Publikation als Summe(AnzahlTodesfall) wenn NeuerTodesfall in (0,1); Delta zum Vortag als Summe(AnzahlTodesfall) wenn NeuerTodesfall in (-1,1)
# Referenzdatum: Erkrankungsdatum bzw. wenn das nicht bekannt ist, das Meldedatum
# AnzahlGenesen: Anzahl der Genesenen in der entsprechenden Gruppe
# NeuGenesen:
# 0: Fall ist in der Publikation für den aktuellen Tag und in der für den Vortag jeweils Genesen
# 1: Fall ist in der aktuellen Publikation Genesen, nicht jedoch in der Publikation des Vortages
# -1: Fall ist in der aktuellen Publikation nicht Genesen, jedoch war er in der Publikation des Vortags Genesen
# -9: Fall ist weder in der aktuellen Publikation noch in der des Vortages Genesen
# damit ergibt sich: Anzahl Genesen der aktuellen Publikation als Summe(AnzahlGenesen) wenn NeuGenesen in (0,1); Delta zum Vortag als Summe(AnzahlGenesen) wenn NeuGenesen in (-1,1)
def get_date_range(dfs):
min_dates = []
for _, df in dfs.items():
min_dates.append(date.fromisoformat(df.index.values.min()))
min_date = min(min_dates)
dates = []
for i in range((date.today() - min_date).days + 1):
dates.append((min_date + timedelta(days=i)).isoformat())
return dates
class DataFetcher:
@staticmethod
def fetch_french_data():
pass
# @staticmethod
# def fetch_all_german_data():
# dfs = []
# with urllib.request.urlopen(
# "https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_COVID19/FeatureServer/0//query?where=Datenstand%3D%27" +
# "20-04-28" + "%27&objectIds=&time=&resultType=none&outFields=*&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&sqlFormat=none&f=pjson&token=") as url:
# json_data = json.loads(url.read().decode())["features"]
# json_data = [x["attributes"] for x in json_data if "attributes" in x]
# if len(json_data) > 0:
# dfs.append(pd.DataFrame(json_data))
# return pd.concat(dfs)
@staticmethod
def fetch_german_data():
start_date = date(2020, 1, 1)
end_date = date.today() + timedelta(days=1)
dfs = []
for single_date in pd.date_range(start_date, end_date):
print("reading: "+str(single_date))
with urllib.request.urlopen(
"https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_COVID19/FeatureServer/0//query?where=Meldedatum%3D%27" + str(
single_date.strftime(
"%Y-%m-%d")) + "%27&objectIds=&time=&resultType=none&outFields=*&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&sqlFormat=none&f=pjson&token=") as url:
json_data = json.loads(url.read().decode())["features"]
json_data = [x["attributes"] for x in json_data if "attributes" in x]
if len(json_data) > 0:
dfs.append(pd.DataFrame(json_data))
return pd.concat(dfs)
@staticmethod
def fetch_italian_data():
load_dotenv()
df = pd.read_csv("https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-regioni/dpc-covid19-ita-regioni.csv")
df.sort_values(by="data", inplace=True)
return df
@staticmethod
def fetch_swiss_data():
load_dotenv()
parser = ConfigParser()
parser.read("../covid19-cases-switzerland/sources.ini")
cantons = list(map(str.upper, parser['cantonal']))
dfs = {}
for canton in cantons:
dfs[canton] = (
pd.read_csv(parser["cantonal"][canton.lower()]).groupby(["date"]).max()
)
# Append empty dates to all
dates = get_date_range(dfs)
df_cases = pd.DataFrame(float("nan"), index=dates, columns=cantons)
df_fatalities = pd.DataFrame(float("nan"), index=dates, columns=cantons)
df_hospitalized = pd.DataFrame(float("nan"), index=dates, columns=cantons)
df_icu = pd.DataFrame(float("nan"), index=dates, columns=cantons)
df_vent = pd.DataFrame(float("nan"), index=dates, columns=cantons)
df_released = pd.DataFrame(float("nan"), index=dates, columns=cantons)
for canton, df in dfs.items():
for d in dates:
if d in df.index:
df_cases[canton][d] = df["ncumul_conf"][d]
df_fatalities[canton][d] = df["ncumul_deceased"][d]
df_hospitalized[canton][d] = df["ncumul_hosp"][d]
df_icu[canton][d] = df["ncumul_ICU"][d]
df_vent[canton][d] = df["ncumul_vent"][d]
df_released[canton][d] = df["ncumul_released"][d]
# Fill to calculate the correct totals for CH
cantons = df_cases.columns
canton_geo = {
"AG": [47.3887506709017, 8.04829959908319],
"AI": [47.3366249625858, 9.41305434728638],
"AR": [47.382878725937, 9.27443680962626],
"BE": [46.948021, 7.44821],
"BL": [47.4854119772813, 7.72572990842221],
"BS": [47.559662, 7.58053],
"CH": [46.8095957, 7.103256],
"FR": [46.8041803910762, 7.15974364171403],
"GE": [46.2050579, 6.126579],
"GL": [47.0209899551849, 8.97917017584858, ],
"GR": [46.8521107310644, 9.53013993916933],
"JU": [47.1711613, 7.7298485],
"LU": [47.0471358210592, 8.32521536164421],
"NE": [46.9947407, 6.8725506],
"NW": [46.95725, 8.365905],
"OW": [46.8984476369729, 8.17648286868192],
"SG": [47.4221404863031, 9.37594858130343],
"SH": [47.697472, 8.63223],
"SO": [47.2083728153487, 7.53011089227976],
"SZ": [47.0234391221245, 8.67474512239957],
"TG": [47.5539632, 8.8730003],
"TI": [46.1999320324997, 9.02266750657928],
"UR": [46.886774, 8.634912],
"VD": [46.552043140147, 6.65230780339362],
"VS": [46.225759, 7.3302457],
"ZG": [47.1499939485641, 8.52330213578886],
"ZH": [47.369091, 8.53801]
}
df_cases.columns = df_cases.columns + "_cases"
df_fatalities.columns = df_fatalities.columns + "_fatalities"
df_hospitalized.columns = df_hospitalized.columns + "_hospitalized"
df_icu.columns = df_icu.columns + "_icu"
df_released.columns = df_released.columns + "_released"
df_merged_temp = df_cases.merge(df_fatalities, how='outer', left_index=True, right_index=True)
df_merged_temp = df_merged_temp.merge(df_hospitalized, how='outer', left_index=True, right_index=True)
df_merged_temp = df_merged_temp.merge(df_icu, how='outer', left_index=True, right_index=True)
df_merged_temp = df_merged_temp.merge(df_released, how='outer', left_index=True, right_index=True)
df_merged_temp.reset_index(inplace=True)
df_merged_temp.fillna(method='ffill', inplace=True)
df_merged_temp.fillna(0, inplace=True)
df_merged_temp = df_merged_temp.rename(columns={'index': 'date'})
data = []
for row_i in range(df_merged_temp.shape[0]):
row = df_merged_temp.iloc[row_i]
for canton in cantons:
d = {"canton": canton}
if not canton == "CH":
for key in ["cases", "fatalities", "hospitalized", "icu", "released"]:
d[key] = row[f"{canton}_{key}"]
d["geo_coordinates_2d"] = canton_geo[canton]
d["date"] = row["date"]
data.append(d)
return pd.DataFrame(data)
@staticmethod
def fetch_us_data():
path = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_US.csv"
df = pd.read_csv(path)
df["City"] = df["Admin2"]
df.drop(columns=["Admin2"], inplace=True)
df.sort_values("City", inplace=True)
df = df[["UID", "FIPS", "City", "Province_State", "Lat", "Long_"] + [x for x in df.columns if "/" in x]]
return df
if __name__ == "__main__":
DataFetcher.fetch_us_data()