本文目录导读:

我来提供一个完整的自动分班脚本方案,包含多种分班策略和详细的代码示例。
基础版本 - 随机分班
import pandas as pd
import numpy as np
from datetime import datetime
class AutoClassAssigner:
def __init__(self, student_file, class_count=5):
"""
初始化分班器
:param student_file: 学生数据文件路径
:param class_count: 班级数量
"""
self.students_df = pd.read_excel(student_file)
self.class_count = class_count
self.classes = {}
def random_assign(self, seed=None):
"""随机分班"""
if seed:
np.random.seed(seed)
# 打乱顺序
shuffled = self.students_df.sample(frac=1).reset_index(drop=True)
# 平均分配到各班
for i in range(self.class_count):
start_idx = i * len(shuffled) // self.class_count
end_idx = (i + 1) * len(shuffled) // self.class_count
self.classes[f'班级{i+1}'] = shuffled.iloc[start_idx:end_idx]
return self.classes
def export_result(self, filename='分班结果.xlsx'):
"""导出分班结果"""
with pd.ExcelWriter(filename) as writer:
# 汇总表
summary_data = []
for class_name, class_df in self.classes.items():
summary_data.append({
'班级': class_name,
'人数': len(class_df)
})
pd.DataFrame(summary_data).to_excel(writer, sheet_name='班级人数汇总', index=False)
# 每个班级单独一页
for class_name, class_df in self.classes.items():
class_df.to_excel(writer, sheet_name=class_name, index=False)
均衡分班版本
class BalancedClassAssigner(AutoClassAssigner):
def __init__(self, student_file, class_count=5, balance_columns=['性别', '成绩']):
super().__init__(student_file, class_count)
self.balance_columns = balance_columns
def balanced_assign(self):
"""均衡分班 - 确保各班在特定属性上相近"""
df = self.students_df.copy()
# 初始化各班列表
class_members = {f'班级{i+1}': [] for i in range(self.class_count)}
# 按学科成绩排序(蛇形分配)
if '成绩' in self.balance_columns:
df = df.sort_values('成绩', ascending=False)
# 蛇形分配算法
direction = 1 # 1表示正序,-1表示倒序
current_class = 0
for idx, student in df.iterrows():
# 选择班级
class_name = f'班级{current_class + 1}'
class_members[class_name].append(student)
# 切换班级
current_class += direction
# 到达边界时反向
if current_class >= self.class_count:
current_class = self.class_count - 1
direction = -1
elif current_class < 0:
current_class = 0
direction = 1
# 转换为DataFrame
for class_name, members in class_members.items():
self.classes[class_name] = pd.DataFrame(members)
return self.classes
def check_balance(self):
"""检查各班均衡性"""
print("=" * 50)
print("分班均衡性检查")
print("=" * 50)
for col in self.balance_columns:
if col not in ['性别', '班级平均成绩']:
print(f"\n{col}分布情况:")
for class_name, class_df in self.classes.items():
if col == '性别':
male_count = len(class_df[class_df[col] == '男'])
female_count = len(class_df[class_df[col] == '女'])
print(f"{class_name}: 男 {male_count}人, 女 {female_count}人")
elif col == '成绩':
avg = class_df[col].mean()
print(f"{class_name}: 平均成绩 {avg:.1f}分")
指标优化分班版本
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
class OptimizedClassAssigner(AutoClassAssigner):
def __init__(self, student_file, class_count=5, weights=None):
"""
:param weights: 各指标的权重字典,如 {'成绩': 0.6, '性别': 0.2, '地区': 0.2}
"""
super().__init__(student_file, class_count)
self.weights = weights or {'成绩': 0.5, '性别': 0.2, '地区': 0.3}
def optimize_assign(self):
"""基于K-means的优化分班"""
df = self.students_df.copy()
# 特征编码
features = []
# 数值特征标准化
numeric_cols = [col for col in ['成绩', '年龄'] if col in df.columns]
if numeric_cols:
for col in numeric_cols:
df[f'{col}_norm'] = (df[col] - df[col].mean()) / df[col].std()
features.append(f'{col}_norm')
# 分类特征one-hot编码
if '性别' in df.columns:
df['性别男'] = (df['性别'] == '男').astype(int)
features.append('性别男')
# 区域编码
if '地区' in df.columns:
df = pd.get_dummies(df, columns=['地区'], prefix='地区')
features += [col for col in df.columns if col.startswith('地区_')]
# K-means聚类
X = df[features].values
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 每个样本的类别数等于班级数
kmeans = KMeans(n_clusters=self.class_count, random_state=42)
df['分配组'] = kmeans.fit_predict(X_scaled)
# 从各组中轮流抽取学生到各班
class_members = {f'班级{i+1}': [] for i in range(self.class_count)}
for group in range(self.class_count):
group_students = df[df['分配组'] == group]
for idx, (i, student) in enumerate(group_students.iterrows()):
# 分配到不同班级
class_idx = (idx + group) % self.class_count
class_name = f'班级{class_idx + 1}'
class_members[class_name].append(student)
# 整理结果
for class_name, members in class_members.items():
self.classes[class_name] = pd.DataFrame(members).drop(columns=['分配组'])
return self.classes
带权重约束的分班
class WeightedClassAssigner(AutoClassAssigner):
def __init__(self, student_file, class_count=5, constraints=None):
super().__init__(student_file, class_count)
# 约束条件示例
self.constraints = constraints or {
'性别平衡': True,
'成绩均衡': True,
'地区分散': True,
'男生班级': None # 可以指定哪些班级全男生
}
def assign_with_constraints(self):
"""带约束条件的分班"""
df = self.students_df.copy()
# 初始化
class_members = {f'班级{i+1}': [] for i in range(self.class_count)}
used_indices = set()
# 处理特殊班级(如男生班)
if self.constraints.get('男生班级'):
male_students = df[df['性别'] == '男']
special_class = self.constraints['男生班级']
male_count = len(male_students) // self.class_count
class_members[special_class] = list(male_students.head(male_count).index)
used_indices.update(male_students.head(male_count).index)
# 蛇形分配剩余学生
remaining = df.drop(index=used_indices)
remaining = remaining.sort_values('成绩', ascending=False)
# 按成绩分组,每组从不同成绩段抽取
group_size = len(remaining) // self.class_count
for class_idx in range(self.class_count):
current_members = []
for group in range(self.class_count):
start = group * group_size
end = (group + 1) * group_size
if start < len(remaining):
pool = remaining.iloc[start:end]
if len(pool) > 0:
# 从该段随机选一个学生
chosen_idx = np.random.choice(pool.index)
current_members.append(chosen_idx)
used_indices.add(chosen_idx)
remaining = remaining.drop(index=chosen_idx)
class_members[f'班级{class_idx + 1}'].extend(current_members)
# 处理剩余学生
for i, idx in enumerate(remaining.index):
class_name = f'班级{i % self.class_count + 1}'
class_members[class_name].append(idx)
# 转换格式
for class_name, indices in class_members.items():
self.classes[class_name] = df.loc[indices]
return self.classes
使用示例
def main():
# 示例数据生成
import random
# 生成100个学生样本数据
students = []
names = [f'学生{i+1}' for i in range(100)]
for i, name in enumerate(names):
students.append({
'姓名': name,
'学号': f'2024{i+1:04d}',
'性别': np.random.choice(['男', '女'], p=[0.5, 0.5]),
'成绩': np.random.normal(75, 15), # 正态分布的成绩
'地区': np.random.choice(['A区', 'B区', 'C区', 'D区']),
'年龄': np.random.choice([15, 16, 17])
})
df = pd.DataFrame(students)
df.to_excel('students.xlsx', index=False)
# 使用分班器
print("=" * 60)
print("自动分班系统")
print("=" * 60)
# 1. 随机分班
print("\n1. 随机分班")
assigner = AutoClassAssigner('students.xlsx', class_count=5)
result = assigner.random_assign()
assigner.export_result('random_assign_result.xlsx')
# 2. 均衡分班
print("\n2. 均衡分班")
balanced_assigner = BalancedClassAssigner('students.xlsx', class_count=5)
balanced_assigner.balanced_assign()
balanced_assigner.check_balance()
balanced_assigner.export_result('balanced_assign_result.xlsx')
# 3. 优化分班
print("\n3. 优化分班")
optimizer = OptimizedClassAssigner('students.xlsx', class_count=5)
optimizer.optimize_assign()
optimizer.export_result('optimized_assign_result.xlsx')
# 4. 带约束分班
print("\n4. 带约束分班")
constrained = WeightedClassAssigner('students.xlsx', class_count=5)
constrained.assign_with_constraints()
constrained.export_result('constrained_assign_result.xlsx')
print("\n分班完成!结果已保存到Excel文件。")
if __name__ == "__main__":
main()
分班效果评估
class ClassEvaluator:
@staticmethod
def evaluate(class_assigner):
"""评估分班效果"""
if not class_assigner.classes:
print("没有分班结果!")
return
print("\n" + "=" * 60)
print("分班效果评估")
print("=" * 60)
# 1. 人数统计
print("\n【人数统计】")
for class_name, class_df in class_assigner.classes.items():
total = len(class_df)
male = len(class_df[class_df['性别'] == '男']) if '性别' in class_df.columns else 0
female = total - male
print(f"{class_name}: 共{total}人 (男{male}人, 女{female}人)")
# 2. 成绩统计
if '成绩' in class_assigner.students_df.columns:
print("\n【成绩分析】")
scores = []
for class_name, class_df in class_assigner.classes.items():
avg = class_df['成绩'].mean()
std = class_df['成绩'].std()
max_score = class_df['成绩'].max()
min_score = class_df['成绩'].min()
scores.append(avg)
print(f"{class_name}: 平均{avg:.1f}分, 最高{max_score:.1f}分, 最低{min_score:.1f}分")
# 班级间差异
if len(scores) > 1:
diff = max(scores) - min(scores)
print(f"\n班级平均分差距: {diff:.1f}分")
if diff < 5:
print("均衡性: 很好!")
elif diff < 10:
print("均衡性: 一般")
else:
print("均衡性: 需要改进")
这个脚本提供了完整的分班解决方案,可以根据实际需求选择不同的分班策略,并支持自定义约束条件。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播