一、数据说明:
考生分数.xlsx为某地区本科上线考生的高考成绩表。
招生计划.xlsx为全国高校在某地区的招生计划。
志愿填报表.xlsx为某地区考生的志愿填报情况。
其志愿内容表示某高校某专业,形如:1035:10。其中1035为学校代码,10为校内专业代码。
要求:
根据以上3表,确定所有考生的最终录取情况。
录取情况可能为:
某高校某专业,形如:1035:10。
当未被录取时,录取情况填“未录取”。
二、录取规则
对所有考生按照高考总分以及其他属性排序确定其唯一排名。
首先按总分排序,当总分相同时,按数学成绩排。
当数学相同时,按物理排。
当物理相同时,按化学排。
当化学相同时,按出生日期排,出生日期小的排名靠前。
若以上还相同,按考生编号排,考生编号小的排名靠前。
按照排名由前往后,对每个考生分别投档,投档时按照该考生的志愿1~志愿8的顺序投递。当目标专业人未录满时,投入目标专业,该考生录取完成。当目标专业人满时,考虑其下一个志愿。若该考生所有志愿用完时,仍未能投档,则该考生的录取状态为“未录取”。
三、python代码
1、读取数据
import pandas as pd
import numpy as np
# 读取数据
scores = pd.read_excel('考生分数.xlsx')
plans = pd.read_excel('招生计划.xlsx')
choices = pd.read_excel('志愿填报表.xlsx')
2、合并,生成x:y型
plans['学校代码']=plans['学校代码'].astype(str)
plans['校内专业代码']=plans['校内专业代码'].astype(str)
zhiyuan=plans['学校代码']+':'+plans['校内专业代码']
plans['专业']=zhiyuan
plans['专业']
0 1035:1
1 1035:2
2 1035:3
3 1035:4
4 1035:5
...
6445 1362:35
6446 1362:36
6447 1362:37
6448 1362:38
6449 1362:39
Name: 专业, Length: 6450, dtype: object
3、将招生计划表转为字典
plans_dict = plans.set_index(['专业']).to_dict()['招生计划数']
plans_dict
4、排序
scores['总分'] = scores['语文'] + scores['数学'] + scores['英语'] + scores['物理'] + scores['化学']
scores = scores.sort_values(by=['总分', '数学', '物理', '化学', '出生日期', '考生编号'],
ascending=[False, False, False, False, True, True]).reset_index(drop=True)
scores
考生编号 | 出生日期 | 语文 | 数学 | 英语 | 物理 | 化学 | 总分 | |
---|---|---|---|---|---|---|---|---|
0 | 52020290802 | 2002-06-11 | 148 | 144 | 145 | 140 | 149 | 726 |
1 | 52020212061 | 2002-02-17 | 144 | 149 | 141 | 144 | 147 | 725 |
2 | 52020309252 | 2002-04-18 | 143 | 144 | 150 | 141 | 147 | 725 |
3 | 52020285405 | 2001-10-07 | 149 | 137 | 147 | 145 | 146 | 724 |
4 | 52020243143 | 2001-12-04 | 147 | 140 | 150 | 139 | 147 | 723 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
52756 | 52020281734 | 2002-06-07 | 99 | 97 | 92 | 104 | 147 | 539 |
52757 | 52020290191 | 2001-09-27 | 96 | 97 | 101 | 104 | 141 | 539 |
52758 | 52020291203 | 2001-10-06 | 99 | 97 | 96 | 99 | 148 | 539 |
52759 | 52020287552 | 2002-04-08 | 95 | 96 | 99 | 107 | 142 | 539 |
52760 | 52020214160 | 2002-04-15 | 99 | 94 | 92 | 107 | 147 | 539 |
52761 rows × 8 columns
5、合并scores,choices
df = pd.merge(scores,choices,on='考生编号')
df
考生编号 | 出生日期 | 语文 | 数学 | 英语 | 物理 | 化学 | 总分 | 志愿1 | 志愿2 | 志愿3 | 志愿4 | 志愿5 | 志愿6 | 志愿7 | 志愿8 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 52020290802 | 2002-06-11 | 148 | 144 | 145 | 140 | 149 | 726 | 1297:19 | 1262:2 | 1224:15 | 1127:28 | NaN | NaN | NaN | NaN |
1 | 52020212061 | 2002-02-17 | 144 | 149 | 141 | 144 | 147 | 725 | 1180:23 | 1333:23 | 1047:12 | 1120:2 | 1083:11 | 1039:8 | 1050:7 | 1169:19 |
2 | 52020309252 | 2002-04-18 | 143 | 144 | 150 | 141 | 147 | 725 | 1128:17 | 1350:5 | 1353:34 | 1245:6 | 1120:6 | NaN | NaN | NaN |
3 | 52020285405 | 2001-10-07 | 149 | 137 | 147 | 145 | 146 | 724 | 1220:21 | 1245:26 | 1069:8 | 1072:4 | 1224:9 | 1312:23 | 1334:7 | NaN |
4 | 52020243143 | 2001-12-04 | 147 | 140 | 150 | 139 | 147 | 723 | 1325:3 | 1297:13 | 1046:12 | 1130:1 | 1333:19 | 1322:1 | 1101:16 | 1153:27 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
52756 | 52020281734 | 2002-06-07 | 99 | 97 | 92 | 104 | 147 | 539 | 1127:13 | 1080:1 | 1267:22 | 1196:21 | 1196:22 | 1052:16 | 1104:1 | 1132:2 |
52757 | 52020290191 | 2001-09-27 | 96 | 97 | 101 | 104 | 141 | 539 | 1128:23 | 1155:2 | 1335:17 | 1196:25 | 1170:8 | 1075:23 | 1329:2 | 1343:1 |
52758 | 52020291203 | 2001-10-06 | 99 | 97 | 96 | 99 | 148 | 539 | 1085:4 | 1213:10 | 1335:9 | 1094:7 | 1291:6 | 1301:25 | 1222:15 | 1188:28 |
52759 | 52020287552 | 2002-04-08 | 95 | 96 | 99 | 107 | 142 | 539 | 1262:31 | 1353:21 | 1126:5 | 1306:11 | 1143:21 | 1282:5 | 1215:19 | NaN |
52760 | 52020214160 | 2002-04-15 | 99 | 94 | 92 | 107 | 147 | 539 | 1323:27 | 1288:31 | 1094:20 | 1102:23 | 1102:31 | 1236:5 | 1215:1 | NaN |
52761 rows × 16 columns
6、定义函数,关于投档和录取
def admission(df, plans_dict):
# 定义投档状态和录取状态的字典
admission_status = {}
admission_result = {}
# 遍历每个考生
for i, row in df.iterrows():
# 初始化投档状态,将每个志愿的投档状态全部置为False
admission_status[row['考生编号']] = {j:False for j in range(1,9)}
# 遍历每个志愿,找到可以投档的志愿
for j in range(1,9):
major = row[f'志愿{j}']
if major in plans_dict and plans_dict[major] > 0 and not admission_status[row['考生编号']][j]:
# 如果目标专业人未录满,则投入目标专业,修改招生计划数和考生的投档状态
plans_dict[major] -= 1
admission_status[row['考生编号']][j] = True
admission_result[row['考生编号']] = major
break
# 如果目标专业人已录满,继续找下一个志愿
if j == 8:
admission_result[row['考生编号']] = '未录取'
return admission_result
admission_result = admission(df, plans_dict)
print(admission_result) # 输出录取结果
7、将录取结果转换为数据框
result_df = pd.DataFrame.from_dict(admission_result, orient='index', columns=['录取专业']).sort_index()
result_df
录取专业 | |
---|---|
52020210104 | 1196:24 |
52020210110 | 1188:15 |
52020210112 | 1113:6 |
52020210113 | 1170:23 |
52020210115 | 1061:23 |
... | ... |
52020310096 | 1037:11 |
52020310097 | 1228:15 |
52020310099 | 未录取 |
52020310102 | 1243:12 |
52020310103 | 1073:3 |
52761 rows × 1 columns
8、保存文件
# 将数据框保存为xlsx文件
result_df.to_excel('result.xlsx', index_label='考生编号')