如何按年、月分组获取员工上月薪资?
解决员工薪资数据新增上月薪资列的问题
我来帮你搞定这个需求!你之前的问题主要是找错了分组维度,而且没处理好数据的排序和偏移逻辑。我们一步步来实现你想要的效果:
1. 先做基础的数据格式处理
首先得把带$的薪资转换成数值(方便后续计算),同时确保数据按员工、年份、月份正确排序——这是后续分组偏移的关键:
import pandas as pd # 加载你的示例数据 data = [ ["PersonA", 2001, 1, "$50000"], ["PersonB", 2001, 5, "$65000"], ["PersonB", 2002, 1, "$75000"], ["PersonB", 2002, 3, "$100000"], ["PersonC", 2002, 5, "$75000"], ["PersonC", 2002, 6, "$100000"], ["PersonC", 2003, 3, "$110000"], ["PersonC", 2003, 9, "$130000"], ["PersonC", 2004, 3, "$150000"], ["PersonC", 2005, 3, "$200000"] ] df = pd.DataFrame(data, columns=["Employee", "year", "month", "Salary"]) # 去掉$符号,转换薪资为整数 df["Salary_num"] = df["Salary"].str.replace("$", "").astype(int) # 按员工、年份、月份排序,保证顺序正确 df = df.sort_values(by=["Employee", "year", "month"]).reset_index(drop=True)
2. 分组获取上一条记录的薪资
你的核心需求是每个员工的上一条薪资记录(第一条记录填0),用groupby+shift(1)就能完美实现:
# 按Employee分组,shift(1)取上一行的薪资,空值(第一条记录)填0 df["previous_month_salary_num"] = df.groupby("Employee")["Salary_num"].shift(1).fillna(0) # 把数值转回带$的格式,0保持原样 df["previous month salary"] = df["previous_month_salary_num"].apply(lambda x: f"${int(x)}" if x != 0 else 0) # 整理成你需要的最终列结构 final_df = df[["Employee", "year", "month", "Salary", "previous month salary"]] print(final_df)
运行这段代码后,就能得到你想要的结果:
Employee year month Salary previous month salary 0 PersonA 2001 1 $50000 0 1 PersonB 2001 5 $65000 0 2 PersonB 2002 1 $75000 $65000 3 PersonB 2002 3 $100000 $75000 4 PersonC 2002 5 $75000 0 5 PersonC 2002 6 $100000 $75000 6 PersonC 2003 3 $110000 $100000 7 PersonC 2003 9 $130000 $110000 8 PersonC 2004 3 $150000 $130000 9 PersonC 2005 3 $200000 $150000
3. 针对真实数据的补充方案
如果你的真实数据每个员工每个月都有完整记录,上面的方法依然适用。要是你想严格匹配“上月的年月”(避免排序可能出现的问题),可以把年月转换成日期后再合并:
# 生成每月第一天的日期列 df["date"] = pd.to_datetime(df[["year", "month"]].assign(day=1)) # 计算上月日期 df["prev_date"] = df["date"] - pd.DateOffset(months=1) # 合并对应员工上月的薪资 prev_salary_map = df[["Employee", "date", "Salary_num"]].rename( columns={"date": "prev_date", "Salary_num": "previous_month_salary_num"} ) df = df.merge(prev_salary_map, on=["Employee", "prev_date"], how="left") # 处理空值和格式 df["previous_month_salary_num"] = df["previous_month_salary_num"].fillna(0) df["previous month salary"] = df["previous_month_salary_num"].apply(lambda x: f"${int(x)}" if x != 0 else 0) # 整理最终列 final_df = df[["Employee", "year", "month", "Salary", "previous month salary"]]
这个方法更严谨,能精准匹配到每个员工的上月薪资,不管数据排序情况如何。
内容的提问来源于stack exchange,提问作者kspmm
相关产品推荐
相关产品推荐

