最终的样子

改动如下:
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))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值