可以说我有以下数据,并且需要下面显示的输出。

import pandas as pd

data = [
    {'job_id': 1, 'employee': 'Joe', 'date': datetime.date(2019, 6, 10)},
    {'job_id': 1, 'employee': 'Joe', 'date': datetime.date(2019, 6, 11)},
    {'job_id': 2, 'employee': 'Joe', 'date': datetime.date(2019, 6, 12)},
    {'job_id': 2, 'employee': 'Joe', 'date': datetime.date(2019, 6, 13)},
    {'job_id': 1, 'employee': 'Joe', 'date': datetime.date(2019, 6, 14)},
    {'job_id': 1, 'employee': 'Joe', 'date': datetime.date(2019, 6, 17)},
    {'job_id': 2, 'employee': 'Jill', 'date': datetime.date(2019, 6, 10)},
    {'job_id': 2, 'employee': 'Jill', 'date': datetime.date(2019, 6, 11)},
    {'job_id': 1, 'employee': 'Jill', 'date': datetime.date(2019, 6, 12)},
    {'job_id': 1, 'employee': 'Jill', 'date': datetime.date(2019, 6, 13)},
    {'job_id': 3, 'employee': 'Jill', 'date': datetime.date(2019, 6, 14)}
]

data_df = pd.DataFrame(data)

output_data = [
    {'job_id': 1, 'employee': 'Joe', 'start_date': datetime.date(2019, 6, 10), 'end_date': datetime.date(2019, 6, 11)},
    {'job_id': 2, 'employee': 'Joe', 'start_date': datetime.date(2019, 6, 12), 'end_date': datetime.date(2019, 6, 13)},
    {'job_id': 1, 'employee': 'Joe', 'start_date': datetime.date(2019, 6, 14), 'end_date': datetime.date(2019, 6, 17)},
    {'job_id': 2, 'employee': 'Jill', 'start_date': datetime.date(2019, 6, 10), 'end_date': datetime.date(2019, 6, 11)},
    {'job_id': 1, 'employee': 'Jill', 'start_date': datetime.date(2019, 6, 12), 'end_date': datetime.date(2019, 6, 13)},
    {'job_id': 3, 'employee': 'Jill', 'start_date': datetime.date(2019, 6, 14), 'end_date': datetime.date(2019, 6, 14)}
]

output_df = pd.DataFrame(output_data)

本质上,我让表按employee顺序排列,然后按升序排列。我需要汇总给定工作的员工的start/end日期。注意事项:

  1. 员工可以先工作,再转到另一份工作,然后再回到第一份工作(请参阅Joe-他先完成工作1,然后进行2,然后再回到1)。这应该显示每个转换的条目(请参见输出数据中的行)。
  2. 该员工可能连续几天都没有工作(例如,周末休息2天),但是如果他在Thurs和Fri上班,然后在周一返回工作岗位,那么Thurs-Monday都将获得一份工作。同样,在工作1的第二天见Joe
  3. 员工可能只工作一天。在这种情况下,start_date和end_date应该是同一天(请参阅作业3的Jill)。
  4. 一名员工每天只能从事一份工作。

如果不是连续的时间段,那么我将转到数据透视表,按user/job分组,然后按最大日期和最小日期进行汇总。但是,当我寻找具有相同employeejob_id的连续行时,我不确定如何进行分组。

分析解答

IIUC,您可以通过两个groupby来这样做:

# to mask the jobs chunks separately
s  = data_df.groupby('employee').job_id.apply(lambda x: x.ne(x.shift()).cumsum())

out_df = data_df.groupby(['employee', s]).agg({'job_id':'first', 'date':{'min','max'}})

给出:

                job_id        date            
                job_id         max         min
employee job_id                               
Jill     1           2  2019-06-11  2019-06-10
         2           1  2019-06-13  2019-06-12
         3           3  2019-06-14  2019-06-14
Joe      1           1  2019-06-11  2019-06-10
         2           2  2019-06-13  2019-06-12
         3           1  2019-06-17  2019-06-14

可以通过以下方式将其更改为您的表格:

out_df.columns = ['job_id', 'end_date', 'start_date']
out_df = out_df.reset_index(level=1,drop=True).reset_index()