我有两个拥有员工数据的数据框如下所示。一个数据文件包含员工数据,包括员工生病的日期,另一个数据文件包含员工工作的日期(即作为日期范围显示)。 我想通过查看特定员工的“病假”在“工作范围”中的位置来合并这两个文件(希望在熊猫中)。例如,在下面的图像/数据中,员工1在2015年11月25日,2015年12月23日和2015年12月10日生病。这些分别属于2015年11月21日 - 2015年11月29日,2015年12月21日 - 2015年12月29日和2015年10月9日 - 2015年10月17日的“工作范围”。
员工工作日期数据:
╔══════════╦════════════╦════════════╗
║ Employee ║ datein ║ dateout ║
╠══════════╬════════════╬════════════╣
║ 1 ║ 11/21/2015 ║ 11/29/2015 ║
║ 2 ║ 12/9/2015 ║ 12/14/2015 ║
║ 3 ║ 11/10/2015 ║ 11/19/2015 ║
║ 4 ║ 11/11/2015 ║ 11/17/2015 ║
║ 5 ║ 11/30/2015 ║ 12/8/2015 ║
║ 1 ║ 12/21/2015 ║ 12/29/2015 ║
║ 2 ║ 1/7/2016 ║ 1/12/2016 ║
║ 3 ║ 12/10/2015 ║ 12/19/2015 ║
║ 4 ║ 12/10/2015 ║ 12/16/2015 ║
║ 5 ║ 12/30/2015 ║ 1/7/2016 ║
║ 1 ║ 10/9/2015 ║ 10/17/2015 ║
║ 2 ║ 10/27/2015 ║ 11/1/2015 ║
║ 3 ║ 9/28/2015 ║ 10/7/2015 ║
║ 4 ║ 9/29/2015 ║ 10/5/2015 ║
╚══════════╩════════════╩════════════╝
员工病假日期数据:
╔══════════╦════════════╦═══════════╗
║ Employee ║ sickDate ║ sickness ║
╠══════════╬════════════╬═══════════╣
║ 1 ║ 11/25/2015 ║ flu ║
║ 10 ║ 11/21/2015 ║ hd ║
║ 21 ║ 9/20/2015 ║ other ║
║ 1 ║ 12/23/2015 ║ other ║
║ 4 ║ 12/13/2015 ║ vacationx ║
║ 7 ║ 7/21/2015 ║ cough ║
║ 3 ║ 10/1/2015 ║ rash ║
║ 4 ║ 10/5/2015 ║ other ║
║ 5 ║ 1/7/2016 ║ eyex ║
║ 2 ║ 12/12/2015 ║ tanx ║
║ 1 ║ 10/12/2015 ║ fatiguex ║
╚══════════╩════════════╩═══════════╝
合并数据:
╔══════════╦════════════╦════════════╦════════════╦═══════════╗
║ Employee ║ datein ║ dateout ║ sickDate ║ sickness ║
╠══════════╬════════════╬════════════╬════════════╬═══════════╣
║ 1 ║ 11/21/2015 ║ 11/29/2015 ║ 11/25/2015 ║ flu ║
║ 2 ║ 12/9/2015 ║ 12/14/2015 ║ 12/12/2015 ║ tanx ║
║ 3 ║ 11/10/2015 ║ 11/19/2015 ║ ║ ║
║ 4 ║ 11/11/2015 ║ 11/17/2015 ║ ║ ║
║ 5 ║ 11/30/2015 ║ 12/8/2015 ║ ║ ║
║ 1 ║ 12/21/2015 ║ 12/29/2015 ║ 12/23/2015 ║ other ║
║ 2 ║ 1/7/2016 ║ 1/12/2016 ║ ║ ║
║ 3 ║ 12/10/2015 ║ 12/19/2015 ║ ║ ║
║ 4 ║ 12/10/2015 ║ 12/16/2015 ║ 12/13/2015 ║ vacationx ║
║ 5 ║ 12/30/2015 ║ 1/7/2016 ║ 1/7/2016 ║ eyex ║
║ 1 ║ 10/9/2015 ║ 10/17/2015 ║ 10/12/2015 ║ fatiguex ║
║ 2 ║ 10/27/2015 ║ 11/1/2015 ║ ║ ║
║ 3 ║ 9/28/2015 ║ 10/7/2015 ║ 10/1/2015 ║ rash ║
║ 4 ║ 9/29/2015 ║ 10/5/2015 ║ 10/5/2015 ║ other ║
╚══════════╩════════════╩════════════╩════════════╩═══════════╝
我如何在pandas或python中做到这一点? (谢谢你的帮助!)
答案 0 :(得分:0)
您需要将此数据作为 df1 添加到pd.DataFrame( ... )
和set_index('Employee')
╔══════════╦════════════╦════════════╗
║ Employee ║ datein ║ dateout ║
╠══════════╬════════════╬════════════╣
║ 1 ║ 11/21/2015 ║ 11/29/2015 ║
║ 2 ║ 12/9/2015 ║ 12/14/2015 ║
║ 3 ║ 11/10/2015 ║ 11/19/2015 ║
║ 4 ║ 11/11/2015 ║ 11/17/2015 ║
║ 5 ║ 11/30/2015 ║ 12/8/2015 ║
║ 1 ║ 12/21/2015 ║ 12/29/2015 ║
║ 2 ║ 1/7/2016 ║ 1/12/2016 ║
║ 3 ║ 12/10/2015 ║ 12/19/2015 ║
║ 4 ║ 12/10/2015 ║ 12/16/2015 ║
║ 5 ║ 12/30/2015 ║ 1/7/2016 ║
║ 1 ║ 10/9/2015 ║ 10/17/2015 ║
║ 2 ║ 10/27/2015 ║ 11/1/2015 ║
║ 3 ║ 9/28/2015 ║ 10/7/2015 ║
║ 4 ║ 9/29/2015 ║ 10/5/2015 ║
╚══════════╩════════════╩════════════╝

然后将此数据作为 df2 和pd.DataFrame( ... )
set_index('Employee')
╔══════════╦════════════╦═══════════╗
║ Employee ║ sickDate ║ sickness ║
╠══════════╬════════════╬═══════════╣
║ 1 ║ 11/25/2015 ║ flu ║
║ 10 ║ 11/21/2015 ║ hd ║
║ 21 ║ 9/20/2015 ║ other ║
║ 1 ║ 12/23/2015 ║ other ║
║ 4 ║ 12/13/2015 ║ vacationx ║
║ 7 ║ 7/21/2015 ║ cough ║
║ 3 ║ 10/1/2015 ║ rash ║
║ 4 ║ 10/5/2015 ║ other ║
║ 5 ║ 1/7/2016 ║ eyex ║
║ 2 ║ 12/12/2015 ║ tanx ║
║ 1 ║ 10/12/2015 ║ fatiguex ║
╚══════════╩════════════╩═══════════╝

最后,df = df1.join(df2).reset_index()
答案 1 :(得分:0)
考虑内部和外部pandas merge方法。下面假设日期是datetime
格式,可能需要从字符串对象转换:
workdf['datein'] = pd.to_datetime(workdf['datein'])
workdf['dateout'] = pd.to_datetime(workdf['dateout'])
sickdf['sickDate'] = pd.to_datetime(sickdf['sickDate'])
# INNER MERGE ON BOTH DFs WHERE SICK DAYS REPEAT FOR MATCHING EMPLOYEE ROW IN WORK DAYS
mergedf = pd.merge(workdf, sickdf, on='Employee', how="inner")
# OUTER MERGE TO KEEP ALL WORK DAY RECORDS WITH FILTERED SICK DAYS DATA SET
finaldf = pd.merge(mergedf[(mergedf['sickDate'] - mergedf['datein'] >= 0) &
(mergedf['dateout'] - mergedf['sickDate'] >= 0)],
workdf, on=['Employee', 'datein', 'dateout'], how="outer")
finaldf = finaldf.sort(['Employee','datein','dateout']).reset_index(drop=True)
结果
# Employee datein dateout sickDate sickness
#0 1 2015-10-09 2015-10-17 2015-10-12 fatiguex
#1 1 2015-11-21 2015-11-29 2015-11-25 flu
#2 1 2015-12-21 2015-12-29 2015-12-23 other
#3 2 2015-10-27 2015-11-01 NaT NaN
#4 2 2015-12-09 2015-12-14 2015-12-12 tanx
#5 2 2016-01-07 2016-01-12 NaT NaN
#6 3 2015-09-28 2015-10-07 2015-10-01 rash
#7 3 2015-11-10 2015-11-19 NaT NaN
#8 3 2015-12-10 2015-12-19 NaT NaN
#9 4 2015-09-29 2015-10-05 2015-10-05 other
#10 4 2015-11-11 2015-11-17 NaT NaN
#11 4 2015-12-10 2015-12-16 2015-12-13 vacationx
#12 5 2015-11-30 2015-12-08 NaT NaN
#13 5 2015-12-30 2016-01-07 2016-01-07 eyex