С начала 2022 года вспышка коронавируса стала значительным испытанием для нашего региона. Чтобы помочь в борьбе с пандемией, необходимо иметь общее представление о распространении заболевания по всему региону и по городам. В этом контексте наша команда, опираясь на существующие проекты, разработала данный пример.
@Huang Chengpeng отвечает за сбор данных, разработку и реализацию проекта;
@Luo Mingwei участвует в технических обсуждениях и демонстрации проекта.
Источник данных: DXY-COVID-19-Data2. Извлечение необходимых данных
2.1 Чтение данных
```Python
data = pd.read_csv('data/DXYArea.csv')
```
2.2 Просмотр названий столбцов
```Python
print(list(data.columns))
```
```Python
['continentName', 'continentEnglishName', 'countryName', 'countryEnglishName', 'provinceName', 'provinceEnglishName', 'province_zipCode', 'province_confirmedCount', 'province_suspectedCount', 'province_curedCount', 'province_deadCount', 'cityName', 'cityEnglishName', 'city_zipCode', 'city_confirmedCount', 'city_suspectedCount', 'city_curedCount', 'city_deadCount', 'updateTime']
```
Соответственно, это обозначает названия континентов, названия континентов на английском, названия стран, названия стран на английском, названия провинций, названия провинций на английском, почтовые индексы провинций, общее количество подтвержденных случаев в провинции, общее количество подозрительных случаев в провинции, общее количество вылечившихся в провинции, общее количество смертей в провинции, названия городов, названия городов на английском, почтовые индексы городов, общее количество подтвержденных случаев в городе, общее количество подозрительных случаев в городе, общее количество вылечившихся в городе, общее количество смертей в городе, время обновления. Нам нужны названия провинций, общее количество подтвержденных случаев в провинции, общее количество вылечившихся в провинции, общее количество смертей в провинции, названия городов, общее количество подтвержденных случаев в городе, общее количество вылечившихся в городе, общее количество смертей в городе, время обновления. 2.3 Удаление избыточных столбцов
```Python
data.drop(columns=['continentName', 'continentEnglishName', 'countryName', 'countryEnglishName', 'provinceEnglishName',
'province_zipCode', 'cityEnglishName', 'city_zipCode', 'province_suspectedCount', 'city_suspectedCount'], inplace=True)
```
2.4 Выбрать данные для провинции Гуандун
```Python
data = data[data['provinceName'] == '广东省']
```
2.5 Выбрать данные для 2022 года
```Python
data = data[data['updateTime'] >= '2022-01-01']
```
Предварительная обработка данных
3.1 Изменение названий колонок
Английские названия слишком длинные, заменим их на китайские.
data.rename(columns={'provinceName': '省名', 'province_confirmedCount': '省累计确诊', 'province_curedCount': '省累计治愈', 'province_deadCount': '省累计死亡',
'cityName': '市名', 'city_confirmedCount': '市累计确诊', 'city_curedCount': '市累计治愈', 'city_deadCount': '市累计死亡', 'updateTime': '更新时间'}, inplace=True)
3.2 Добавление колонки с текущим количеством подтвержденных случаев
data['省现有确诊'] = data['省累计确诊'] - data['省累计治愈'] - data['省累计死亡']
data['市现有确诊'] = data['市累计确诊'] - data['市累计治愈'] - data['市累计死亡']
3.3 Группировка по городам
cites = set(data['市名'])
cites -= {'待明确地区'}
print(cites)
cites_data = dict()
for city in cites:
cites_data[city] = data[data['市名'] == city].copy()
# print(f'查看{city}更新时间:\n',cites_data[city]['更新时间'].values)
# Обнаружено, что даты обновления не являются непрерывными, и некоторые даты повторяются, что требует обработки
3.4 Обработка повторяющихся дат, оставляем только самую свежую дату обновления ```Python for city in cites: temp_date = '2022-05-20' for i, row in cites_data[city].iterrows(): if row['Обновление времени'][:10] == temp_date: cites_data[city].drop(i, inplace=True) else: temp_date = row['Обновление времени'][:10] cites_data[city].loc[:, 'Обновление времени'] = pd.to_datetime( cites_data[city]['Обновление времени'].apply(lambda x: x[:10])).values cites_data[city].reset_index(inplace=True, drop=True)
3.5 Обработка пропущенных дат, заполнение данными из ближайших дат ```Python
# код для заполнения пропущенных значений
for city in cites:
# Создаем новый DataFrame для хранения заполненных данных
new_data = pd.DataFrame(columns=cites_data[city].columns)
current_date = datetime.datetime(2022, 5, 20)
current_index = 0
for i, row in cites_data[city].iterrows():
next_date = row['更新时间']
days = (current_date - next_date).days
if days > 1:
for j in range(1, days):
new_row = row.copy()
new_row['省累计确诊'] = round(
(cites_data[city].iloc[current_index]['省累计确诊'] - row['省累计确诊']) / days * j + row['省累计确诊'])
new_row['省累计治愈'] = round(
(cites_data[city].iloc[current_index]['省累计治愈'] - row['省累计治愈']) / days * j + row['省累计治愈'])
new_row['省累计死亡'] = round(
(cites_data[city].iloc[current_index]['省累计死亡'] - row['省累计死亡']) / days * j + row['省累计死亡'])
new_row['省现有确诊'] = new_row['省累计确诊'] - \
new_row['省累计治愈'] - new_row['省累计死亡']
new_row['市累计确诊'] = round(
(cites_data[city].iloc[current_index]['市累计确诊'] - row['市累计确诊']) / days * j + row['市累计确诊'])
new_row['市累计治愈'] = round(
(cites_data[city].iloc[current_index]['市累计治愈'] - row['市累计治愈']) / days * j + row['市累计治愈'])
new_row['市累计死亡'] = round(
(cites_data[city].iloc[current_index]['市累计死亡'] - row['市累计死亡']) / days * j + row['市累计死亡'])
new_row['市现有确诊'] = new_row['市累计确诊'] - \
new_row['市累计治愈'] - new_row['市累计死亡']
new_row['更新时间'] = next_date + datetime.timedelta(days=j)
new_row = new_row.to_frame().T
new_row['更新时间'] = pd.to_datetime(
new_row['更新时间'])
``````python
apply(lambda x: str(x)[:10])).values # Заполненные данные добавляем в новый DataFrame new_data = pd.concat([new_data, new_row], ignore_index=True) ``````markdown current_index = i current_date = next_date
else:
current_index = i
current_date = next_date
```python
# Добавляем новые данные к исходным данным
cites_data[city] = pd.concat(
[cites_data[city], new_data], ignore_index=True)
# Сортируем по дате
cites_data[city].sort_values(by='Обновление', inplace=True)
cites_data[city].loc[:, 'Обновление'] = pd.to_datetime(
cites_data[city]['Обновление'].apply(lambda x: str(x)[:10])).values
# Пересоздаем индексы
cites_data[city].reset_index(inplace=True, drop=True)
``` 3. 6 Добавление количества новых случаев заболевания по провинциям и городам ежедневно
``` ```Python
for city in cites:
for i, row in cites_data[city].iterrows():
if i == 0:
cites_data[city]['省新增确诊'] = ''
cites_data[city]['市新增确诊'] = ''
cites_data[city].loc[0, '省新增确诊'] = 0
cites_data[city].loc[0, '市新增确诊'] = 0
else:
cites_data[city].loc[i, '市新增确诊'] = row['市累计确诊'] - cites_data[city].iloc[i-1]['市累计确诊'] if row['市累计确诊'] - cites_data[city].iloc[i-1]['市累计确诊'] > 0 else 0
cites_data[city].loc[i, '省新增确诊'] = row['省累计确诊'] - cites_data[city].iloc[i-1]['省累计确诊'] if row['省累计确诊'] - cites_data[city].iloc[i-1]['省累计确诊'] > 0 else 0
# Изменение порядка столбцов
cites_data[city] = cites_data[city][['省名', '省新增确诊', '省现有确诊', '省累计确诊', '省累计治愈', '省累计死亡',
'市名', '市新增确诊', '市现有确诊', '市累计确诊', '市累计治愈', '市累计死亡', '更新时间']]
```
4. Построение линейных графиков
4.1 Построение и сохранение линейных графиков ежедневного количества новых случаев заболевания, текущего количества случаев заболевания и общего количества случаев заболевания по провинции
```Python
if not os.path.exists('./output/'):
os.makedirs('./output/')
data = cites_data['广州']
sns.lineplot(data=data, x='更新时间', y='省新增确诊')
plt.savefig('output/省新增确诊数.jpg', dpi=1024)
plt.clf()
sns.lineplot(data=data, x='更新时间', y='省现有确诊')
plt.savefig('output/省现有确诊数.jpg', dpi=1024)
plt.clf()
sns.lineplot(data=data, x='更新时间', y='省累计确诊')
plt.savefig('output/省累计确诊数.jpg', dpi=1024)
plt.clf()
``` 4.2 Построение и сохранение линейных графиков ежедневного количества новых случаев заболевания, текущего количества случаев заболевания и общего количества случаев заболевания для каждого города```Python
if not os.path.exists('./output/'):
os.makedirs('./output/')
data = None
for city in cites:
data = pd.concat([data, cites_data[city]], ignore_index=True)
sns.lineplot(data=data, x='更新时间', y='市新增确诊', hue='市名', style='市名')
plt.savefig('output/各市新增确诊数.jpg', dpi=1024)
plt.clf()
sns.lineplot(data=data, x='更新时间', y='市现有确诊', hue='市名', style='市名')
plt.savefig('output/各市现有确诊数.jpg', dpi=1024)
plt.clf()
sns.lineplot(data=data, x='更新时间', y='市累计确诊', hue='市名', style='市名')
plt.savefig('output/各市累计确诊数.jpg', dpi=1024)
plt.clf()
```5. Построение динамической карты 5.1 Построение динамической карты ежедневного количества подтвержденных случаев в Гuangdong Province в 2022 году
```Python
def current_confirmed_timeline_map() -> Timeline:
global cites
tl = Timeline(init_opts=opts.InitOpts(page_title="Динамическая карта ежедневного количества подтвержденных случаев в Гуандунской провинции в 2022 году",
theme=ThemeType.DARK,
width="1300px", height="666px"),
)
index = 0
cites = list(cites)
for date in pd.date_range(start='2022-01-01', end='2022-05-19'):
date = str(date)[:10]
confirmedCount = []
# assert 0
for city in cites:
confirmedCount.append(cites_data[city].iloc[index]['市现有确诊'])
zipped = zip([x + '市' for x in cites], confirmedCount)
f_map = (
Map(init_opts=opts.InitOpts(width="1000px",
height="600px",
page_title="Динамическая карта ежедневного количества подтвержденных случаев в Гуандунской провинции в 2022 году",
bg_color=None))
.add(series_name="Количество подтвержденных случаев",
data_pair=[list(z) for z in zipped],
maptype="Гуандун",
is_map_symbol_show=False)
.set_global_opts(
title_opts=opts.TitleOpts(title="Динамическая карта ежедневного количества подтвержденных случаев в Гуандунской провинции в 2022 году",
subtitle=f"{date[5:7]}月{date[8:10]}日数据\n",
pos_left="center", ),
legend_opts=opts.LegendOpts(
is_show=True, pos_top="40px", pos_right="30px"),
visualmap_opts=opts.VisualMapOpts(
``````markdown
.set_series_opts(label_opts=opts.LabelOpts(is_show=True),
markpoint_opts=opts.MarkPointOpts(
symbol_size=[90, 90], symbol='circle'),
effect_opts=opts.EffectOpts(is_show=True, )
)
),
.add(f_map, f"{date[5:7]}月{date[8:10]}日")
.add_schema(is_timeline_show=True, # 是否显示
play_interval=500, # 播放间隔
symbol=None, # 图标
is_loop_play=True # 循环播放
)
)
index += 1
return tl
current_confirmed_timeline_map().render('./output/2022年广东省每日现有确诊动态地图.html')
```
``` 5. 2 Построение динамической карты ежедневного увеличения числа подтвержденных случаев в Гuangdong省 в 2022 году ```Python
def new_confirmed_timeline_map() -> Timeline:
global cites
tl = Timeline(init_opts=opts. InitOpts(page_title="Динамическая карта ежедневного увеличения числа подтвержденных случаев в Гуандунской провинции в 2022 году",
theme=ThemeType. DARK,
width="1300px", height="666px"),
)
index = 0
cites = list(cites)
for date in pd. date_range(start='2022-01-01', end='2022-05-19'):
date = str(date)[:10]
confirmedCount = []
# assert 0
for city in cites:
confirmedCount. append(cites_data[city]. iloc[index]['市新增确诊'])
zipped = zip([x + '市' for x in cites], confirmedCount)
f_map = (
Map(init_opts=opts. InitOpts(width="1000px",
height="600px",
page_title="Динамическая карта ежедневного увеличения числа подтвержденных случаев в Гуандунской провинции в 2022 году",
bg_color=None))
. add(series_name="Новый подтвержденный случай",
data_pair=[list(z) for z in zipped],
maptype="广东",
is_map_symbol_show=False)
. set_global_opts(
title_opts=opts. TitleOpts(title="Динамическая карта ежедневного увеличения числа подтвержденных случаев в Гуандунской провинции в 2022 году",
subtitle=f"{date[5:7]}月{date[8:10]}日数据\n",
pos_left="center", ),
legend_opts=opts. LegendOpts(
is_show=True, pos_top="40px", pos_right="30px"),
visualmap_opts=opts. VisualMapOpts(
is_piecewise=True, range_text=['', ''], pieces=[
{"min": 70, "color": "#751d0d"},
{"min": 40, "max": 69, "color": "#ae2a23"},
{"min": 20, "max": 39, "color": "#d6564c"},
{"min": 10, "max": 19, "color": "#f19178"},
{"min": 5, "max": 9, "color": "#f7d3a6"}, {"min": 1, "max": 4, "color": "#fdf2d3"},
{"min": 0, "max": 0, "color": "#AAFFAA"}
]),
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=True),
markpoint_opts=opts.MarkPointOpts(
symbol_size=[90, 90], symbol='circle'
),
effect_opts=opts.EffectOpts(is_show=True)
)
)
tl.add(f_map, f"{date[5:7]} месяца {date[8:10]}")
tl.add_schema(is_timeline_show=True, # 是否显示
play_interval=500, # 播放间隔
symbol=None, # 图标
is_loop_play=True # 循环播放
)
index += 1
return tl
new_confirmed_timeline_map().render('./output/2022年广东省每日新增确诊动态地图.html')## Результаты экспериментов
- Динамика числа новых случаев по провинции

- Динамика числа текущих случаев по провинции

- Динамика числа накопленных случаев по городам

- Динамика числа новых случаев по городам

- Динамика числа текущих случаев по городам

- Динамика числа накопленных случаев по городам

- [Динамика новых случаев по провинции Гуандун за 2022 год](./output/2022年广东省每日新增确诊动态地图.html)
Скриншот:

- [Динамика текущих случаев по провинции Гуандун за 2022 год](./output/2022年广东省每日现有确诊动态地图.html)
Скриншот:

## Внимание
В связи с отсутствием данных за некоторые даты, мы заполняем пропущенные данные на основе ближайших доступных данных, поэтому результаты могут отличаться.
## Участие в проекте
1. Fork этот репозиторий
2. Создайте ветку Feat_xxx
3. Отправьте код
4. Создайте Pull Request## Ссылки
1. [DXY-COVID-19-Data](https://github.com/BlankerL/DXY-COVID-19-Data/releases/tag/2022.05.20)
2. [Python для визуализации данных о пандемии](https://www.jianshu.com/p/ce968c9d5d94)
3. Вэй Вэй-йи, Ли Сяо-хун, Гао Чжун-линь. Python для анализа и визуализации данных: видео-курс (2-е издание). Пекин: Издательство Tsinghua, 2021.7
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )