Python按时间段分组(带容差)

2024-10-01 02:32:52 发布

您现在位置:Python中文网/ 问答频道 /正文

此数据集中有三列:ID(唯一员工标识)、WorkComplete(指示所有工作何时完成)和DateDiff(从开始日期算起的天数)。我希望将DaysDiff列根据特定的时间段进行分组,并添加一层宽容或宽大。对于模拟数据,我将时间间隔设置为30天

Group 0: 0-30 DateDiff (with a 30 day extra window if 'Y' is not found)
Group 1: 31-60 DateDiff (with a 30 day extra window if 'Y' is not found)
Group 2: 61-90 DateDiff (with a 30 day extra window if 'Y' is not found)

我能够创建非常基本的代码并分配分组,但我在额外的30天窗口方面遇到了问题。例如,如果员工在上述时间段内完成了工作(Y),则他们将收到属性分组。对于下面的ID 111,您可以看到此人没有在前30天内完成工作,因此我给他们额外的30天时间来完成工作。如果他们完成了他们的工作,那么我们看到的第一个实例是“Y”,它在前面的分组中分组

df = pd.DataFrame({'ID':[111, 111, 111, 111, 111, 111, 112, 112, 112],
                   'WorkComplete':['N', 'N', 'Y', 'N', 'N', 'N', 'N', 'Y', 'Y'],
                   'DaysDiff': [0, 29, 45, 46, 47, 88, 1, 12, 89]})

输入

ID   WorkComplete      DaysDiff 
111  N                 0
111  N                 29
111  Y                 45
111  N                 46
111  N                 47
111  N                 88
123  N                 1 
123  Y                 12
123  Y                 89        

输出

ID   WorkComplete      DaysDiff   Group
111  N                 0          0
111  N                 29         0
111  Y                 45         0   <---- note here the grouping is 0 to provide extra time
111  N                 46         1   <---- back to normal
111  N                 47         1   
111  N                 88         2
123  N                 1          0
123  Y                 12         0
123  Y                 89         2
minQ1 = 0
highQ1 = 30
minQ2 = 31
highQ2 = 60
minQ2 = 61
highQ2 = 90

def Group_df(df):
    if (minQ1 <= df['DateDiff'] <= highQ1): return '0'
    elif (minQ1 <= df['DateDiff'] <= highQ1): return '1'
    elif (minQ2 <= df['DateDiff'] <= highQ2): return '2'

df['Group'] = df.apply(Group_df, axis = 1)

我遇到的麻烦是,如果该人没有完成工作,我将允许额外的30天。我以上的努力只是部分地试图解决这个问题


Tags: iddfifiswithgroupnotwindow
1条回答
网友
1楼 · 发布于 2024-10-01 02:32:52
  1. 您可以使用np.select作为主要条件
  2. 然后,使用mask表示您提到的特定条件s是每组所有{}值第一个索引位置。然后,我临时将assign{}作为一个新列,这样我就可以对照df.index(索引)检查行,以返回满足条件的行。第二个条件是,如果组号是previos代码行的1

df['Group'] = np.select([df['DaysDiff'].between(0,30), 
                         df['DaysDiff'].between(31,60), 
                         df['DaysDiff'].between(61,90)],
                         [0,1,2])
s = df[df['WorkComplete'] == 'Y'].groupby('ID')['DaysDiff'].transform('idxmin')
df['Group'] = df['Group'].mask((df.assign(s=s)['s'].eq(df.index)) & (df['Group'].eq(1)), 0)
df
Out[1]: 
    ID WorkComplete  DaysDiff  Group
0  111            N         0      0
1  111            N        29      0
2  111            Y        45      0
3  111            N        46      1
4  111            N        47      1
5  111            N        88      2
6  123            N         1      0
7  123            Y        12      0
8  123            Y        89      2

相关问题 更多 >