改动如下:
1、改用字典存储各种学生数据:做到了在安排考室时要用的模块名字和数据DataFrame的对应。
2、3.0版本中是学生和考场数据同时生成的方式:改为两者分别生成后,再结合为考场数据。
3、 某组合的 学生数据按照需要的考室数量划分为n块,再和其他组合学生的数据块 ,不足考场容量的数据块补充空白行达到容量值,最后按顺寻拼接为所有考室的数据。
4、考场数据值由两列构成—考号和地点。按照考试容量依次生成。
import pandas as pd
import numpy as np
import random
# 这两个参数的默认设置都是False 中文行列名的对齐必备
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
pd.set_option('display.max_rows', 1999) #最大显××行,××列
pd.set_option('display.max_columns',11)
path0 = 'F:\python-code\处理过数据1\年级选科.xlsx'
data = pd.read_excel(path0)
needcols = ['姓名','班级','日语','首选','组合','Y/N']
def data_N_arrange(data=data ,needcols=needcols):
allcols = data.columns.values
colsdel = [i for i in allcols if i not in needcols]
for col in colsdel:
del data[col]
data = data.fillna('英')
data_YN_groupby = data.groupby('Y/N')
data_N_df = data_YN_groupby.get_group('N')
data_NShouxuan_groupby = data_N_df.groupby('首选')
data_NRiyu_groupby = data_N_df.groupby('日语')
data = data_YN_groupby.get_group('Y')
del data[needcols[-1]]
data_N_dicts = {'N':data_YN_groupby.get_group('N'),'N物': data_NShouxuan_groupby.get_group('物'), 'N历':data_NShouxuan_groupby.get_group('历'),
'N日': data_NRiyu_groupby.get_group('日'),'N英':data_NRiyu_groupby.get_group('英')}
return data , data_N_dicts
def data_Y_arrange(data = data):
zuhes = data['组合'].unique()
data_Zuhe_groupby = data.groupby('组合')
data_Y_dicts = {}
data_Zuhe_Len_dicts ={}
for i in zuhes:
temp_Zuhe_dict = {i:data_Zuhe_groupby.get_group(i)}
data_Y_dicts.update(temp_Zuhe_dict)
data_Zuhe_Len_dict = {i :len(data_Zuhe_groupby.get_group(i))}
data_Zuhe_Len_dicts.update(data_Zuhe_Len_dict)
data_Riyu_groupby = data.groupby('日语')
data_Shouxuan_groupby = data.groupby('首选')
temp_df8 = data_Shouxuan_groupby.get_group('物')
temp_df8_gy = temp_df8.groupby('日语')
temp_df7 = data_Shouxuan_groupby.get_group('历')
temp_df7_gy = temp_df7.groupby('日语')
temp_Y_dict ={'日':data_Riyu_groupby.get_group('日'),'英':data_Riyu_groupby.get_group('英'),'物':temp_df8_gy.get_group('英'),'历':temp_df7_gy.get_group('英')}
data_Y_dicts.update(temp_Y_dict)
return data_Y_dicts , data_Zuhe_Len_dicts
data , data_N_dicts = data_N_arrange(data ,needcols)
data_N_names = list(data_N_dicts.keys())
data_Y_dicts , data_Zuhe_Len_dicts = data_Y_arrange(data)
data_Y_names = list(data_Y_dicts.keys())
data_Zuhe_Len_names = list(data_Zuhe_Len_dicts.keys()) #组合 的名称 ['化地', '化生', '生政', '生地', '化政', '政地']
data_Zuhe_Len_values = list(data_Zuhe_Len_dicts.values()) #组合对应的人数 [157, 151, 120, 187, 78, 264]
#print('data_Y_dicts.keys:',data_Y_names,'\n','data_N_dicts.keys:',data_N_names,'\n','data_Zuhe_Len_dicts.keys:',data_Zuhe_Len_names)
##############################################################
###以上是把要用到的数据处理成 单独的df 并采用 字典存储:data_N_dicts 和 data_Y_dicts
##############################################################
path1 = 'F:\python-code\数据源\考场容量.xlsx'
room = pd.read_excel(path1)
del room['类型']
def room_supplys(room=room):
room_supplys = list(room.容量)
room_supplys_tytles = room.容量.unique()
room_supplys_nums_dicts ={} # 各类容量 的考室 数量 {40: 19, 32: 6, 28: 1}
for i in room_supplys_tytles:
room_supplys_nums_dicts.update({i:room_supplys.count(i)})
return room_supplys_nums_dicts
room_supplys_tytles_dicts =room_supplys(room)
room_supplys_tytles_names =list(room_supplys_tytles_dicts.keys()) # 考室容量的类型 [40, 32, 28]
room_supplys_tytles_values =list(room_supplys_tytles_dicts.values())
#print(room_supplys_tytles_names,room_supplys_tytles_values,data_Zuhe_Len_values)
def min(a,b):
if a>b:
return b
else :
return a
def mins(nums=[]):
for i in nums:
for j in nums:
if j<i:
small =j
return small
def sumlist(nums=[]):
sum=0
for i in nums:
sum+=i
return sum
def tytles_limits(num1=room_supplys_tytles_names,num2=data_Zuhe_Len_values,num3=room_supplys_tytles_values,names = data_Zuhe_Len_names):
rolltimes =0
leixin = []
dxes = []
anpais = []
for j in range(len(num2)):
for i in range(num3[0]+1):
for ii in range(num3[1]+1):
for iii in range(num3[2]+1):
try:
temp_sum = i * 40 + ii * 32 + iii * 28
temp_dx = temp_sum - num2[j]
if temp_dx < 0 or temp_dx > 23:
continue
except:
pass
#print(names[j],"{}*40 +{}*32 +{}*28=".format(i,ii,iii),temp_sum)
rolltimes +=1
temp_sum = i * 40 + ii * 32 + iii * 28
temp_dx = temp_sum - num2[j]
if 10>=temp_dx >=0:
#print(names[j],temp_dx,"{}*40 +{}*32 +{}*28=".format(i,ii,iii),temp_sum)
leixin.append((names[j]))
dxes.append(temp_dx)
anpais.append([i,ii,iii])
elif temp_dx >40:
break
anpais_df = pd.DataFrame({'类型':leixin,'空位数':dxes,'安排':anpais})
return anpais_df
anpais_df = tytles_limits()
#print(anpais_df)
anpais_df_Zuhe_Names_locs =[]
for i in range(len(data_Zuhe_Len_names)) :
#print(anpais_df.loc[anpais_df['类型']==data_Zuhe_Len_names[i]],len(anpais_df.loc[anpais_df['类型']==data_Zuhe_Len_names[i]]))
anpais_df_Zuhe_Names_locs.append(len(anpais_df.loc[anpais_df['类型']==data_Zuhe_Len_names[i]]))
# anpais_df.loc[anpais_df['类型']==data_Zuhe_Len_names[i]]
# 在表 anpais_df的列 类型里找 和 data_Zuhe_Len_names[i]组合的名字一致的 行,
#整句的意思是 某组合 占了几行就 即 独自考虑安排时有几个可行解
needseats = sumlist(data_Zuhe_Len_values)
supplyseats = sumlist(room.容量)
supply_kongs = supplyseats-needseats
jieda_df = pd.DataFrame({'40人': [], '32人': [], '28人': [],'组合':[]})
def find_kexing(locslist=[],jieda_df=jieda_df):
rolltimes1 =0
j = 0
for i1 in range(locslist[0]):
for i2 in range(locslist[0],sumlist(locslist[:2])):
for i3 in range(sumlist(locslist[:2]),sumlist(locslist[:3])):
for i4 in range(sumlist(locslist[:3]),sumlist(locslist[:4])):
for i5 in range(sumlist(locslist[:4]),sumlist(locslist[:5])):
for i6 in range(sumlist(locslist[:5]),sumlist(locslist[:6])):
used40 = anpais_df['安排'].loc[i1][0] + anpais_df['安排'].loc[i2][0] + anpais_df['安排'].loc[i3][0] + anpais_df['安排'].loc[i4][0] + anpais_df['安排'].loc[i5][0] + anpais_df['安排'].loc[i6][0]
used32 = anpais_df['安排'].loc[i1][1] + anpais_df['安排'].loc[i2][1] + anpais_df['安排'].loc[i3][1] + anpais_df['安排'].loc[i4][1] + anpais_df['安排'].loc[i5][1] + anpais_df['安排'].loc[i6][1]
used28 = anpais_df['安排'].loc[i1][2] + anpais_df['安排'].loc[i2][2] + anpais_df['安排'].loc[i3][2] + anpais_df['安排'].loc[i4][2] + anpais_df['安排'].loc[i5][2] + anpais_df['安排'].loc[i6][2]
if used40>room_supplys_tytles_dicts[40] or used32 +used40> room_supplys_tytles_dicts[40]+room_supplys_tytles_dicts[32] or used40+used32+used28 >room_supplys_tytles_dicts[40]+room_supplys_tytles_dicts[32]+room_supplys_tytles_dicts[28]:
continue
rolltimes1 +=1
dxall = anpais_df['空位数'].loc[i1]+anpais_df['空位数'].loc[i2]+anpais_df['空位数'].loc[i3]+anpais_df['空位数'].loc[i4]+anpais_df['空位数'].loc[i5]+anpais_df['空位数'].loc[i6]
if dxall <= supply_kongs:
if used40 <= room_supplys_tytles_dicts[40]:
if used32 <= room_supplys_tytles_dicts[32] + room_supplys_tytles_dicts[40] - used40:
if used28 <= room_supplys_tytles_dicts[32] + room_supplys_tytles_dicts[40] + \
room_supplys_tytles_dicts[28] - used40 - used32:
# print(anpais_df['安排'].loc[i1],anpais_df['安排'].loc[i2],anpais_df['安排'].loc[i3],anpais_df['安排'].loc[i4],anpais_df['安排'].loc[i5],anpais_df['安排'].loc[i6],)
if used40 == room_supplys_tytles_values[0] and used32 ==room_supplys_tytles_values[1] and used28 ==room_supplys_tytles_values[2]:
j += 1
list0 = [(anpais_df['安排'].loc[i1][0]), anpais_df['安排'].loc[i2][0],
anpais_df['安排'].loc[i3][0], anpais_df['安排'].loc[i4][0],
anpais_df['安排'].loc[i5][0], anpais_df['安排'].loc[i6][0]]
list1 = [anpais_df['安排'].loc[i1][1], anpais_df['安排'].loc[i2][1],
anpais_df['安排'].loc[i3][1], anpais_df['安排'].loc[i4][1],
anpais_df['安排'].loc[i5][1], anpais_df['安排'].loc[i6][1]]
list2 = [anpais_df['安排'].loc[i1][2], anpais_df['安排'].loc[i2][2],
anpais_df['安排'].loc[i3][2], anpais_df['安排'].loc[i4][2],
anpais_df['安排'].loc[i5][2], anpais_df['安排'].loc[i6][2]]
list3 = [list0[0]*40+list1[0]*32+list2[0]*28,list0[1]*40+list1[1]*32+list2[1]*28,list0[2]*40+list1[2]*32+list2[2]*28,list0[3]*40+list1[3]*32+list2[3]*28,list0[4]*40+list1[4]*32+list2[4]*28,list0[5]*40+list1[5]*32+list2[5]*28]
list4 = [data_Zuhe_Len_dicts['化地'],data_Zuhe_Len_dicts['化生'],data_Zuhe_Len_dicts['生政'],data_Zuhe_Len_dicts['生地'],data_Zuhe_Len_dicts['化政'],data_Zuhe_Len_dicts['政地']]
jieda_df = pd.concat([jieda_df,pd.DataFrame({'40人': list0, '32人': list1, '28人': list2,'组合':data_Zuhe_Len_names,'提供':list3,'需求':list4})])
return jieda_df
jieda_df = find_kexing(anpais_df_Zuhe_Names_locs) # jieda_df是所有的可行安排 构成的表
# 下面随机选取一个安排
lines = random.randint(0,len(jieda_df)/6)
finall_df = jieda_df[lines*6:lines*6+6]
#print(finall_df)
places =list(room['地点'])
def newroom(finall_df=finall_df,room=room):
room40 = []
room32 = []
room28 = []
for i in range(len(list(finall_df.columns.values))):
for j in range(6):
if i ==0:
for jj in range(int(finall_df[list(finall_df.columns.values)[i]].loc[j])):
room40.append(finall_df['组合'].loc[j])
if i==1:
for jj in range(int(finall_df[list(finall_df.columns.values)[i]].loc[j])):
room32.append(finall_df['组合'].loc[j])
if i==2:
for jj in range(int(finall_df[list(finall_df.columns.values)[i]].loc[j])):
room28.append(finall_df['组合'].loc[j])
rooms = room40+room32+room28
room.insert(3,column='组合',value=rooms)
newroom()
#print(room)
for i in range(6):
sampler = np.random.permutation(len(data_Y_dicts[finall_df['组合'].loc[i]])) #产生一个随机数列
data_Y_dicts[finall_df['组合'].loc[i]] = data_Y_dicts[finall_df['组合'].loc[i]].take(sampler)
needrows=[]
for i in range(6):
needrows.append(int(finall_df['提供'].loc[i]-finall_df['需求'].loc[i]))
newrow = pd.DataFrame({'姓名':'','班级':'','日语':'','首选':'','组合':''},index=[9999])
for i in range(6):
izuhe = data_Y_names[i]
for ii in range(needrows[i]):
data_Y_dicts[izuhe] = data_Y_dicts[izuhe].append(newrow,ignore_index=True)
#DataFrame 采用 随机数列排序
ff_df = pd.DataFrame()
used_nums=[]
for i in range(6):
temp_df9 = data_Y_dicts[finall_df['组合'].loc[i]][0:int(finall_df['40人'].loc[i])*40]
ff_df = pd.concat([ff_df,temp_df9])
used_nums .append(int((finall_df['40人'].loc[i])*40))
used_nums1=[]
for i in range(6):
temp_df9 = data_Y_dicts[finall_df['组合'].loc[i]][used_nums[i]:used_nums[i]+int(finall_df['32人'].loc[i])*32]
ff_df = pd.concat([ff_df,temp_df9])
used_nums1.append(int(used_nums[i]+(finall_df['32人'].loc[i])*32))
used_nums2=[]
for i in range(6):
temp_df9 = data_Y_dicts[finall_df['组合'].loc[i]][used_nums1[i]:used_nums1[i]+int(finall_df['28人'].loc[i])*28]
ff_df = pd.concat([ff_df,temp_df9])
used_nums2.append(used_nums[i]+(finall_df['28人'].loc[i])*28)
ks_room = list(room['考室号'])
ks_zuhe = list(room['组合'])
kao_num=[]
kao_num1=[]
place =[]
for i in range(len(list(room.容量))):
for j in range(room.容量[i]):
kaohao = str(i + 1).rjust(2, '0') + str(j + 1).rjust(2, '0') + ks_zuhe[i]
kaohao1 = str(i + 1).rjust(2, '0') + str(j + 1).rjust(2, '0') + ks_zuhe[i]
kao_num.append(kaohao)
kao_num1.append(kaohao)
place.append(places[i])
ff_df.insert(5,column='考号+组合',value=kao_num)
ff_df.insert(6,column='地点',value=place)
ff_df.to_excel('F:\python-code\处理过数据1\\5时间段月考安排-四选二科目安排{}.xlsx'.format(1))
temp_df9 = pd.concat([data_Y_dicts['日'],data_N_dicts['N日']])
sampler = np.random.permutation(len(temp_df9)) #产生一个随机数列
temp_df9 = temp_df9.take(sampler)
for i in range(5):
temp_df9 = temp_df9.append(newrow,ignore_index=True)
sampler = np.random.permutation(len(data_Y_dicts['物'])) #产生一个随机数列
data_Y_dicts['物'] = data_Y_dicts['物'].take(sampler)
sampler = np.random.permutation(len(data_Y_dicts['历'])) #产生一个随机数列
data_Y_dicts['历'] = data_Y_dicts['历'].take(sampler)
ff_df = pd.concat([temp_df9,data_Y_dicts['物'],data_Y_dicts['历'],])
for i in range(12):
ff_df = ff_df.append(newrow,ignore_index=True)
del ff_df['Y/N']
ff_df.insert(5,column='考号',value=kao_num1)
ff_df.insert(6,column='地点',value=place)
ff_df.to_excel('F:\python-code\处理过数据1\\5时间段月考安排-语数外科目科目安排{}.xlsx'.format(1))