我正在为我的团队编写轮班名册。考虑,有“ a”个高级主管(一个位置很少,而在另一个位置很少),“ b”个团队负责人(一个位置很少,而另一个位置很少),“ c”个值班经理(很少一个)位置和其他位置)。我想为他们在python中创建一个班次名册。
条件如下。
日期范围为2002年1月1日至2020年12月31日。
将有3个班次,我需要在3个班次中容纳a + b + c资源(〜相等)
每天进行迭代时,如何为每个班次(主要和次要)选择资源?
典型名册应如下所示。
typical roster should look like this
感谢您的任何帮助。
提前感谢
这是我的实现方式。请参见下面的代码并进行说明。
导入声明
import pandas as pd
import datetime as dt
from datetime import datetime
import random
输入要为其准备期间清单的开始日期和结束日期
start_date = dt.date(2020,6,1)
end_date = dt.date(2020,12,31)
创建数据框
roster=pd.DataFrame(columns=['Date',
'Week Number',
'Day',
'INDIA SHIFT 1 PRIMARY',
'INDIA SHIFT 1 Secondary',
'INDIA SHIFT 2 PRIMARY',
'INDIA SHIFT 2 Secondary',
'US SHIFT PRIMARY',
'US SHIFT SECONDARY',
'Weekend On-call Primary',
'Weekend On-call Secondary',
'Duty Manager 1',
'Duty Manager 2',
'Duty Manager Weekend'])
用日期,周号,工作日向DF填充
required_date = []
week_no = []
weekday = []
daterange = pd.date_range(start_date, end_date)
for single_date in daterange:
required_date.append(single_date.strftime("%Y-%m-%d"))
week_no.append(single_date.isocalendar()[1])
weekday.append(single_date.strftime("%A"))
roster['Date'] = required_date
roster['Week Number'] = week_no
roster['Day'] = weekday
我当前的DF看起来像这样enter image description here
然后我正在读取包含资源和假期的输入文件
Resources = pd.read_excel('Input_Data.xlsx', sheet_name='Resources')
Holidays = pd.read_excel('Input_Data.xlsx', sheet_name='Holidays')
资源和假日DF看起来像这样enter image description here
然后,我正在优化假期并删除空值
Holidays.India = Holidays.India.astype(str)
Holidays.US = Holidays.US.astype(str)
Holidays.US = Holidays.US.apply(lambda x : None if x=='NaT' else x)
US_holidays = list(filter(None,list(Holidays.US)))
IND_holidays = list(Holidays.India)
然后,我将明智的假日和普通假日分隔开来>
# segregate holidays whether common holiday or region wise def Optimize_IND_Holidays(IND_holidays): for i in IND_holidays: if(i < roster['Date'][0]): IND_holidays.remove(i) return Optimize_IND_Holidays(IND_holidays) Optimize_IND_Holidays(IND_holidays) def Optimize_US_Holidays(US_holidays): for i in US_holidays: if(i < roster['Date'][0]): US_holidays.remove(i) return Optimize_US_Holidays(US_holidays) Optimize_US_Holidays(US_holidays) common_holidays = [] for i in IND_holidays: for j in US_holidays: if i == j: common_holidays.append(i) IND_holidays.remove(i) US_holidays.remove(i) common_holidays,IND_holidays , US_holidays
基于位置分离资源,因为当一个位置度假时,其他位置资源应转移。
IND_Res = list(Resources.IND) + list(Resources.TL) US_Res = list(Resources.US) US_Res, IND_Res
现在这是我遇到的问题,尽管这是一个临时解决方案,但这并不理想,并且无法实时工作。我在这里所做的是,由于每个班次只有2个资源(偶数和奇数周),所以我也选择分配1个TL,每个班次分配1个高级。除非有假期或周末,否则每周都会有值班经理。我在这里明确分配。因此,我需要一个代码/想法,该如何使用python隐式实现它,而不是手动分配并记住条件编号4。
# get week numbers as list weekno = list(roster['Week Number']) shift1 = {} shift2 = {} shift3 = {} # make a set from the week numbers list and sort them to iterate for i in sorted(list(set(weekno))): if(int(i)%2==0): shift1.update({i:[Resources.TL[0],Resources.IND[0]]}) shift2.update({i:[Resources.TL[1],Resources.IND[1]]}) shift3.update({i:[Resources.US[0],Resources.US[1]]}) else: shift1.update({i:[Resources.TL[1],Resources.IND[1]]}) shift2.update({i:[Resources.TL[0],Resources.IND[0]]}) shift3.update({i:[Resources.US[1],Resources.US[0]]})
周末工作人员清单
weekend_Resources = list(Resources.IND)+list(Resources.US) weekend_Managers = list(Resources.DutyManager)+list(Resources.TL) weekend_combinations = [[a, b] for a in weekend_Resources for b in weekend_Managers if a != b]
我在这里分配工作日和周末的资源,而不分配给假期。
IND_shift1_prim = [] IND_shift1_sec = [] IND_shift2_prim = [] IND_shift2_sec = [] US_shift_prim = [] US_shift_sec = [] Duty1 = [] Duty2 = [] Weekend_prim = [] Weekend_sec = [] for j in sorted(list(set(weekno))): r1 = random.randint(0,len(weekend_combinations)-1) for i in range(len(roster)): if((roster['Week Number'][i]==j) and ((roster['Day'][i] != 'Saturday') and (roster['Day'][i] != 'Sunday'))): #print(roster['Date'][i],roster['Week Number'][i]) IND_shift1_prim.append(shift1[j][0]) IND_shift1_sec.append(shift1[j][1]) IND_shift2_prim.append(shift2[j][0]) IND_shift2_sec.append(shift2[j][1]) US_shift_prim.append(shift3[j][0]) US_shift_sec.append(shift3[j][1]) Duty1.append(Resources.DutyManager[0]) Duty2.append(Resources.DutyManager[1]) Weekend_prim.append("") Weekend_sec.append("") if((roster['Week Number'][i]==j) and ((roster['Day'][i] == 'Saturday') or (roster['Day'][i] == 'Sunday'))): IND_shift1_prim.append("") IND_shift1_sec.append("") IND_shift2_prim.append("") IND_shift2_sec.append("") US_shift_prim.append("") US_shift_sec.append("") Duty1.append("") Duty2.append("") Weekend_prim.append(weekend_combinations[r1][0]) Weekend_sec.append(weekend_combinations[r1][1])
对于假期资源分配,下面是代码。
# for IND, US common holidays for i in range(len(roster)): which_day = datetime.strptime((roster['Date'][i]),"%Y-%m-%d").strftime('%A') if (which_day != 'Saturday' and which_day != 'Sunday'): for j in range(len(common_holidays)): if(roster['Date'][i] == common_holidays[j]): r1 = random.randint(0,len(US_Res)-1) r2 = random.randint(0,len(IND_Res)-1) IND_shift1_prim[i] = IND_Res[r2] IND_shift1_sec[i] = US_Res[r1] IND_shift2_prim[i] = IND_Res[r2] IND_shift2_sec[i] = US_Res[r1] US_shift_prim[i] = US_Res[r1] US_shift_sec[i] = IND_Res[r2] # for India holidays for i in range(len(roster)): for j in range(len(IND_holidays)): if(roster['Date'][i] == IND_holidays[j]): r1 = random.sample(range(0,len(US_Res)),2) IND_shift1_prim[i] = US_Res[r1[0]] IND_shift1_sec[i] = US_Res[r1[1]] IND_shift2_prim[i] = US_Res[r1[1]] IND_shift2_sec[i] = US_Res[r1[0]] US_shift_prim[i] = US_Res[r1[0]] US_shift_sec[i] = US_Res[r1[1]] Duty1[i] = Resources.DutyManager[0] Duty2[i] = Resources.DutyManager[0] #for US holidays for i in range(len(roster)): for j in range(len(US_holidays)): if(roster['Date'][i] == US_holidays[j]): r1 = random.sample(range(0,len(IND_Res)),2) IND_shift1_prim[i] = IND_Res[r1[0]] IND_shift1_sec[i] = IND_Res[r1[1]] IND_shift2_prim[i] = IND_Res[r1[1]] IND_shift2_sec[i] = IND_Res[r1[0]] US_shift_prim[i] = IND_Res[r1[0]] US_shift_sec[i] = IND_Res[r1[1]] Duty1[i] = Resources.DutyManager[1] Duty2[i] = Resources.DutyManager[1]
然后我对照DataFrame本身的长度检查了每个列表的长度,以确保它们相等。
# make sure length of each list is same as number of total days for which roster is being prepared len(IND_shift1_prim),len(IND_shift1_sec),len(IND_shift2_prim),len(IND_shift2_sec),len(US_shift_prim),len(US_shift_sec),len(Duty1),len(Duty2),len(roster)
然后我将列表分配给数据框的列。
roster['INDIA SHIFT 1 PRIMARY'] = IND_shift1_prim roster['INDIA SHIFT 1 Secondary'] = IND_shift1_sec roster['INDIA SHIFT 2 PRIMARY'] = IND_shift2_prim roster['INDIA SHIFT 2 Secondary'] = IND_shift2_sec roster['US SHIFT PRIMARY'] = US_shift_prim roster['US SHIFT SECONDARY'] = US_shift_sec roster['Duty Manager 1'] = Duty1 roster['Duty Manager 2'] = Duty2 roster['Weekend On-call Primary'] = Weekend_prim roster['Weekend On-call Secondary'] = Weekend_sec
最后将数据框导出到excel。
with pd.ExcelWriter('roster.xlsx') as writer: June_roster.T.to_excel(writer, sheet_name = 'June') July_roster.T.to_excel(writer, sheet_name = 'July') August_roster.T.to_excel(writer, sheet_name = 'August') Sep_roster.T.to_excel(writer, sheet_name = 'September') Oct_roster.T.to_excel(writer, sheet_name = 'October') Nov_roster.T.to_excel(writer, sheet_name = 'November') Dec_roster.T.to_excel(writer, sheet_name = 'December')
最终数据框看起来像这样enter image description here
这是我到目前为止所做的。请问有人建议如何将条件4编码为keeipng吗?]
我正在为我的团队编写轮班名册。考虑,有“ a”个前辈(一个位置很少,而另一个位置很少),“ b”个团队负责人(一个位置很少,而另一个位置很少),“ c” ...