我有一个包含员工id、年龄和经验的数据集,我需要根据逻辑计算年龄和经验
输入数据帧
emp_id | 名称 | 年龄exp | 年份||
---|---|---|---|---|
101 | 岩石 | 20 | 5 | 2000|
101 | 岩石 | 20 | 5 | 2001|
101 | 岩石 | 20 | 5 | 2002 |
102 | DED | 25 | 10 | 2000|
102 | DED | 25 | 10 | >2001 |
102 | DED | 25 | 10 | >2002 |
103 | FEG | 30 | 35 | 2000 |
103 | FEG | 30 | 35 | 2001 |
103 | FEG | 30 | 35 | 2002 |
您可以实现如下所需的输出。使用df.groupby
和emp_id
,并按降序检索每组的cumcount
。接下来,从列age
和exp
中减去结果,得到更新的列。
import pandas as pd
data = {'emp_id': {0: 101, 1: 101, 2: 101, 3: 102, 4: 102, 5: 102,
6: 103, 7: 103, 8: 103},
'name': {0: 'Rock', 1: 'Rock', 2: 'Rock', 3: 'DED', 4: 'DED',
5: 'DED', 6: 'FEG', 7: 'FEG', 8: 'FEG'},
'age': {0: 20, 1: 20, 2: 20, 3: 25, 4: 25, 5: 25, 6: 30,
7: 30, 8: 30},
'exp': {0: 5, 1: 5, 2: 5, 3: 10, 4: 10, 5: 10, 6: 35,
7: 35, 8: 35},
'YEAR': {0: 2000, 1: 2001, 2: 2002, 3: 2000, 4: 2001,
5: 2002, 6: 2000, 7: 2001, 8: 2002}
}
df = pd.DataFrame(data)
cumcount = df.groupby('emp_id').cumcount(ascending=False)
df['updated_age'] = df['age'].sub(cumcount)
df['updated_exp'] = df['exp'].sub(cumcount)
print(df)
emp_id name age exp YEAR updated_age updated_exp
0 101 Rock 20 5 2000 18 3
1 101 Rock 20 5 2001 19 4
2 101 Rock 20 5 2002 20 5
3 102 DED 25 10 2000 23 8
4 102 DED 25 10 2001 24 9
5 102 DED 25 10 2002 25 10
6 103 FEG 30 35 2000 28 33
7 103 FEG 30 35 2001 29 34
8 103 FEG 30 35 2002 30 35
更新:对于后面添加的第二个问题:要在每个emp_id
的year
列中的max
的基础上将列updated_year
添加到第二个df
,请尝试如下:
df['updated_year'] = df.groupby('emp_id')['year'].transform(max)
.sub(df.groupby('emp_id').cumcount(ascending=False))
print(df)
emp_id name year updated_year
0 101 Rock 2000 1999
1 101 Rock 2000 2000
2 101 Rock 2001 2001
3 102 DED 2002 2000
4 102 DED 2002 2001
5 102 DED 2000 2002
6 103 FEG 2000 1998
7 103 FEG 2000 1999
8 103 FEG 2000 2000
我的假设是,您希望根据实际年份差异更正age
和exp
(不过我可能错了(。如果是这样的话,你可以试试:
diff = df["YEAR"] - df.groupby("emp_id")["YEAR"].transform("max")
df["update_age"] = df["age"] + diff
df["update_exp"] = df["exp"] + diff
- 构建一个
diff
系列,该系列包含year
与每个empty_id
的最大年份之间的年份差 - 使用
diff
校正age
和exp
样本结果(已校正(:
emp_id name age exp YEAR update_age update_exp
0 101 Rock 20 5 2000 18 3
1 101 Rock 20 5 2001 19 4
2 101 Rock 20 5 2002 20 5
3 102 DED 25 10 2000 23 8
4 102 DED 25 10 2001 24 9
5 102 DED 25 10 2002 25 10
6 103 FEG 30 35 2000 28 33
7 103 FEG 30 35 2001 29 34
8 103 FEG 30 35 2002 30 35