首页 > 解决方案 > Python/Pandas:如何根据其他列值合并行

问题描述

我有一张工作经验数据表。我面临的问题是有些人的工作经历有重叠的日期(即参见第 240、241 和 242、243 行),其中开始日期出现在前一份工作的结束日期之前。这导致夸大了总的经验年限。为了计算总经验年数,我怎样才能获得总工作经验年数,而不会重复计算示例所示的重叠工作。

我最初将每个人的职位任期相加以获得总经验年限,但这并没有考虑到重复计算。

在此处输入图像描述

标签: pythonpandasdataframepandas-groupby

解决方案


尝试:

输入数据:

>>> df
    start_date   end_date
237 2005-01-01 2007-12-01
238 2008-01-01 2012-09-01
239 2012-09-01 2013-07-01
240 2013-07-01 2016-05-01
241 2014-06-01 2016-05-01
242 2016-05-01 2019-10-01
243 2018-01-01 2019-10-01
244 2020-05-01 2021-08-03

end_date首先计算和之间的差异start_date

df['diff1'] = df['end_date'] - df['start_date']
print(df)

    start_date   end_date     diff1
237 2005-01-01 2007-12-01 1064 days
238 2008-01-01 2012-09-01 1705 days
239 2012-09-01 2013-07-01  303 days
240 2013-07-01 2016-05-01 1035 days
241 2014-06-01 2016-05-01  700 days
242 2016-05-01 2019-10-01 1248 days
243 2018-01-01 2019-10-01  638 days
244 2020-05-01 2021-08-03  459 days

现在,减去start_dateend_date - 1仅当开始日期出现在上一行的结束日期之前:

df['diff2'] = (df['start_date'] - df['end_date'].shift()) \
                  .mul(df['start_date'].le(df['end_date'].shift()))
print(df)

  start_date   end_date     diff1     diff2
0 2005-01-01 2007-12-01 1064 days       NaT
1 2008-01-01 2012-09-01 1705 days    0 days
2 2012-09-01 2013-07-01  303 days    0 days
3 2013-07-01 2016-05-01 1035 days    0 days
4 2014-06-01 2016-05-01  700 days -700 days
5 2016-05-01 2019-10-01 1248 days    0 days
6 2018-01-01 2019-10-01  638 days -638 days
7 2020-05-01 2021-08-03  459 days    0 days

最后,添加两diffX列:

df['real'] = df[['diff1', 'diff2']].sum(axis=1)
print(df)

  start_date   end_date     diff1     diff2      real
0 2005-01-01 2007-12-01 1064 days       NaT 1064 days
1 2008-01-01 2012-09-01 1705 days    0 days 1705 days
2 2012-09-01 2013-07-01  303 days    0 days  303 days
3 2013-07-01 2016-05-01 1035 days    0 days 1035 days
4 2014-06-01 2016-05-01  700 days -700 days    0 days
5 2016-05-01 2019-10-01 1248 days    0 days 1248 days
6 2018-01-01 2019-10-01  638 days -638 days    0 days
7 2020-05-01 2021-08-03  459 days    0 days  459 days

真正的经验是df['real'].sum().days / 365,差不多 16 年而不是 19.5 年。您可以将此代码放入一个函数中,并在onapply之后调用它。groupbyperson_id

我将如何创建一个可以与 apply 方法一起使用的函数?

def total_xp_years(df):
    diff1 = df['end_date'] - df['start_date']
    diff2 = df['start_date'] - df['end_date'].shift()
    diff2 *= df['start_date'].le(df['end_date'].shift())
    return (diff1.sum() + diff2.sum()).days / 365

dfxp = df.groupby('person_id').apply(total_xp_years)

推荐阅读