问题描述
我发现了这个关于 Covid 疫苗接种的数据文件,我想查看(部分)人群的疫苗接种覆盖率。实际例子可能会更清楚,所以请耐心等待。
如果我使用 df = pd.read_csv('https://epistat.sciensano.be/Data/COVID19BE_VACC.csv',parse_dates=['DATE'])
读取 csv,我会得到以下结果:
DATE REGION AGEGROUP SEX BRAND DOSE COUNT
0 2020-12-28 Brussels 18-34 F Pfizer-BioNTech A 1
1 2020-12-28 Brussels 45-54 F Pfizer-BioNTech A 2
2 2020-12-28 Brussels 55-64 F Pfizer-BioNTech A 3
3 2020-12-28 Brussels 55-64 M Pfizer-BioNTech A 1
4 2020-12-28 Brussels 65-74 F Pfizer-BioNTech A 2
我对按地区和日期划分的数字特别感兴趣。
所以我使用 df.groupby(['REGION','DATE']).sum()
COUNT
REGION DATE
Brussels 2020-12-28 56
2020-12-30 5
2021-01-05 725
2021-01-06 989
2021-01-07 994
... ...
Wallonia 2021-06-18 49567
2021-06-19 43577
2021-06-20 2730
2021-06-21 37193
2021-06-22 16938
为了比较不同地区的疫苗接种“速度”,我必须使用每个地区的人口将数据从绝对数转换为相对数。
我发现一些帖子解释了如何在这样的多索引数据框中计算百分比,但问题是我想将每个 COUNT 除以原始数据框中不存在的人口数。
人口数量如下
REGION POP
Flanders 6629143
Wallonia 3645243
Brussels 1218255
我认为解决方案必须是循环遍历原始 df 并检查 REGION 或索引级别,但我完全不知道如何进行。这是我想掌握的技术,因为当我想要其他一些具有不同人群(年龄组或性别可能)的子集时,它可能会派上用场。
非常感谢您阅读到这里!
免责声明:我才刚刚开始使用 Python,这是我在 Stack Overflow 上的第一个问题,所以请对我温柔一点......我之所以'我发布此信息是因为我在其他任何地方都找不到答案。这可能是因为我没有把术语记下来,我不知道该找什么 ^_^
解决方法
一种选择是用 set_index
+ rename
重新格式化 population_df
:
population_df = pd.DataFrame({
'REGION': {0: 'Flanders',1: 'Wallonia',2: 'Brussels'},'POP': {0: 6629143,1: 3645243,2: 1218255}
})
denom = population_df.set_index('REGION').rename(columns={'POP': 'COUNT'})
denom
:
COUNT
REGION
Flanders 6629143
Wallonia 3645243
Brussels 1218255
然后div
groupby sum
相对于level=0
的结果:
new_df = df.groupby(['REGION','DATE']).agg({'COUNT': 'sum'}).div(denom,level=0)
new_df
:
COUNT
REGION DATE
Brussels 2020-12-28 0.000046
2020-12-30 0.000004
2021-01-05 0.000595
2021-01-06 0.000812
2021-01-07 0.000816
... ...
Wallonia 2021-06-18 0.013598
2021-06-19 0.011954
2021-06-20 0.000749
2021-06-21 0.010203
2021-06-22 0.004647
或作为新列:
new_df = df.groupby(['REGION','DATE']).agg({'COUNT': 'sum'})
new_df['NEW'] = new_df.div(denom,level=0)
new_df
:
COUNT NEW
REGION DATE
Brussels 2020-12-28 56 0.000046
2020-12-30 5 0.000004
2021-01-05 725 0.000595
2021-01-06 989 0.000812
2021-01-07 994 0.000816
... ... ...
Wallonia 2021-06-18 49567 0.013598
2021-06-19 43577 0.011954
2021-06-20 2730 0.000749
2021-06-21 37193 0.010203
2021-06-22 16938 0.004647
,
您可以在 reset_index()
上运行 groupby
,然后在进行计算的自定义函数上运行 df.apply
:
import pandas as pd
df = pd.read_csv('https://epistat.sciensano.be/Data/COVID19BE_VACC.csv',parse_dates=['DATE'])
df = df.groupby(['REGION','DATE']).sum().reset_index()
def calculate(row):
if row['REGION'] == 'Flanders':
return row['COUNT'] / 6629143
elif row['REGION'] == 'Wallonia':
return row['COUNT'] / 3645243
elif row['REGION'] == 'Brussels':
return row['COUNT'] / 1218255
df['REL_COUNT'] = df.apply(calculate,axis=1) #axis=1 takes the rows as input,axis=0 would run on columns
输出df.head()
:
区域 | 日期 | COUNT | REL_COUNT | |
---|---|---|---|---|
0 | 布鲁塞尔 | 2020-12-28 00:00:00 | 56 | 0.000046 |
1 | 布鲁塞尔 | 2020-12-30 00:00:00 | 5 | 0.000004 |
2 | 布鲁塞尔 | 2021-01-05 00:00:00 | 725 | 0.000595 |
3 | 布鲁塞尔 | 2021-01-06 00:00:00 | 989 | 0.000812 |
4 | 布鲁塞尔 | 2021-01-07 00:00:00 | 994 | 0.000816 |