python - 在 Python Pandas 中创建优先级
问题描述
我有一个大型数据集,其中显示了个人拥有的每个学位以及获得学位的年份。此外,每个人都有一个对应的ID。我正在尝试使用完成学位的年份和完成学位的平均年龄来查找每个人的出生年份。数据集如下所示:
对于平均年龄,我假设博士在 33 岁完成,硕士在 30 岁完成,学士在 22 岁完成。
person_id degree degree_completion year_of_birth
1 PhD 2006 1973
1 BSc 1999 1977
2 Ph.D. 1995 1962
2 MBA 2000 1970
2 B.A. 1987 1965
3 Bachelor of Engineering 2005 1983
4 AB 1997 1975
4 Doctor of Philosophy (PhD) 2003 1970
我已经创建了计算每个人的出生年份的系统,但我不知道如何创建一个优先系统,以便它选择正确的出生年份,因为可以为个人拥有的每个学位计算不同的出生年份。我想要以下优先级:学士出生年份>博士出生年份>硕士出生年份。
我用 groupby 函数和 Categorial 数据类型尝试了很多东西。此外,数据集中有数百种不同的学位形式,因此我一直依赖于使用正则表达式来计算出生年份和创建优先级系统。这是我目前所拥有的,但我找不到将正则表达式实现到其中的方法:
category1 = "^B[a-z]*|AB|A.B.|A.B|S.B."
category2 = "^P[a-z]*|Doctor of Philosophy[a-z]*"
category3 = "^M[a-z]*|Master[a-z]*"
file['edu_degree'] = pd.Categorical(file['edu_degree'], ordered=True, categories=[category1, category2, category3])
file.groupby('person_id')['edu_degree'].transform('max')
此外,这将是我想要的输出(根据优先级替换出生年份):
person_id degree degree_completion year_of_birth
1 PhD 2006 1977
1 BSc 1999 1977
2 Ph.D. 1995 1965
2 MBA 2000 1965
2 B.A. 1987 1965
3 Bachelor of Engineering 2005 1983
4 AB 1997 1975
4 Doctor of Philosophy (PhD) 2003 1975
解决方案
要应用正则表达式,您可以创建一个函数 ( get_diploma
) 一个接一个地测试它们。理想情况下,按最可能的顺序排列(学士学位优先)。
然后您可以按 person_id 分组并找到具有最高优先级的行(get_expected_age
函数)。
import re
category1 = "^B[a-z]*|AB|A.B.|A.B|S.B."
category2 = "^P[a-z]*|Doctor of Philosophy[a-z]*"
category3 = "^M[a-z]*|Master[a-z]*"
diplomas = {category1: 'Bachelor', category2: 'PhD', category3: 'Master'}
ages = {'PhD': 33, 'Master': 30, 'Bachelor': 22}
def get_diploma(s):
# for first matching regexp, return diploma
for k in diplomas:
if re.match(k, s):
return diplomas[k]
df['degree_standardized'] = pd.Categorical(df['degree'].map(get_diploma),
ordered=True,
categories=['Master', 'PhD', 'Bachelor'])
# map the age from the standardized degree. NB. this could be fused with the previous step.
df['expected_age'] = df['degree_standardized'].map(ages)
def get_expected_age(d):
# get degree with highest priority
s = d.sort_values(by='degree_standardized').iloc[-1]
d['year_of_birth'] = s['degree_completion']-s['expected_age']
return d
df.groupby('person_id').apply(get_expected_age)
输出:
person_id degree degree_completion year_of_birth degree_standardized expected_age
0 1 PhD 2006 1977 PhD 33
1 1 BSc 1999 1977 Bachelor 22
2 2 Ph.D. 1995 1965 PhD 33
3 2 MBA 2000 1965 Master 30
4 2 B.A. 1987 1965 Bachelor 22
5 3 Bachelor of Engineering 2005 1983 Bachelor 22
6 4 AB 1997 1975 Bachelor 22
7 4 Doctor of Philosophy (PhD) 2003 1975 PhD 33
推荐阅读
- css - CSS背景渐变过渡不起作用
- javascript - javascript中位置x,y的SVG免费像素
- javascript - 每当渲染或重新渲染组件时,是否有办法控制台日志?
- angular-material - 升级到 Angular 6 后的 angular_material_schematics 文件夹
- node.js - 400 错误请求将 /favicon.ico 作为 req.url 在 express 中返回。
- scala - Scala中的“捆绑”函数
- azure - AAD:是否可以将 Microsoft Graph 开放扩展放入 AD 应用程序清单中的 optionalClaims 中?
- favicon - 添加网站图标的问题
- python-3.x - 当我打开终端时,它总是打印这些错误代码
- python - Python3 - 在不创建列表的情况下遍历 Linux 目录