You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中不用loc查找DataFrame用户输入值及课表分析问题求助

课程表处理作业问题及解决方案

需求与问题

  • 作业限制:仅使用pandas、numpy和基础Python
  • 数据源:含5个工作表(周一至周五)的Excel课程表
  • 核心问题:
    1. 禁用loc函数时,如何根据用户输入课程匹配对应时间、日期、教室信息
    2. 如何找出整周最空闲的时段(行)
  • 需完成7项任务:
    1. Pandas读取课表
    2. 删除不必要的首行
    3. 单门课程查询:返回所有场次的时间、日期、教室编号
    4. 多课程查询:返回指定课程列表的所有场次信息
    5. 查询指定日期的空闲时段
    6. 找出整周使用频率最低的教室
    7. 找出整周最繁忙的实验室名称

现有代码(查找功能失效)

import pandas as pd
import numpy as np

# 读取Excel文件
path = (r'C:\Users\user\Downloads\TimeTable, FSC, Fall-2022.xlsx')

data = pd.read_excel(path,sheet_name=None)
df = pd.concat(data[frame] for frame in data.keys())

# 分别读取每日工作表
mon = pd.read_excel(path,sheet_name = "Monday")
tues = pd.read_excel(path,sheet_name = "Tuesday")
wed = pd.read_excel(path,sheet_name = "Wednesday")
thur = pd.read_excel(path,sheet_name = "Thursday")
fri = pd.read_excel(path,sheet_name = "Friday")

# 构建每日表字典
timetable = {
        "Monday" : mon,
       "Tuesday" : tues,
        "Wednesday" : wed,
        "Thursday" : thur,
        "Friday" : fri,
    }

# 删除各表前2行(索引1、2)
mon.drop([1,2], axis = 0, inplace = True)
tues.drop([1,2], axis = 0, inplace = True)
wed.drop([1,2], axis = 0, inplace = True)
thur.drop([1,2], axis = 0, inplace = True)
fri.drop([1,2], axis = 0, inplace = True)
mon.head()

# 失效的查找代码
df.loc[df[timetable(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'])==subject]]
df.loc[df["Monday"]==subject]

# 用户输入课程名
subject = str(input("Enter the subject you want to search classes for: "))

问题分析与修复方案

1. 禁用loc时的课程查询实现

原代码错误点:

  • 错误将字典timetable当作函数调用,语法错误
  • subject变量定义在查找代码之后,导致未定义
  • 合并表时未保留日期维度,无法区分课程所属日期

替代实现(不使用loc):

# 先获取用户输入
subject = input("输入要查询的课程名称:").strip()

results = []
# 遍历每日表筛选匹配课程
for day, daily_df in timetable.items():
    # 重置索引避免行号混乱
    daily_df = daily_df.reset_index(drop=True)
    # 布尔索引筛选课程(假设课程名在第2列,根据你的表结构调整)
    match_mask = daily_df.iloc[:, 1] == subject
    # 遍历匹配行,收集信息
    for _, row in daily_df[match_mask].iterrows():
        results.append({
            '日期': day,
            '时间': row.iloc[0],  # 假设时间在第1列
            '教室编号': row.iloc[2]  # 假设教室在第3列
        })

# 输出结果
print(pd.DataFrame(results))

2. 查找最空闲的时段(行)

统计每行的课程数量,数量最少的行即为最空闲时段:

# 合并所有每日表并添加日期列
merged_data = []
for day, daily_df in timetable.items():
    daily_df['日期'] = day
    merged_data.append(daily_df)
full_timetable = pd.concat(merged_data, ignore_index=True)

# 统计每行的非空课程数(假设课程列从第2列到倒数第2列)
full_timetable['课程数'] = full_timetable.iloc[:, 1:-1].notna().sum(axis=1)

# 筛选课程数最少的行
min_course_count = full_timetable['课程数'].min()
free_slots = full_timetable[full_timetable['课程数'] == min_course_count]

print("最空闲的时段:")
print(free_slots[[full_timetable.columns[0], '日期']])

全任务整合代码

import pandas as pd
import numpy as np

def load_and_clean_timetable(file_path):
    """读取并清理所有工作表:删除前2行,返回每日表字典"""
    sheets = pd.read_excel(file_path, sheet_name=None)
    cleaned_timetable = {}
    for day, df in sheets.items():
        # 删除索引1、2的行,重置索引
        cleaned_df = df.drop([1, 2], axis=0).reset_index(drop=True)
        cleaned_timetable[day] = cleaned_df
    return cleaned_timetable

def search_single_course(timetable, course_name):
    """查询单门课程的所有场次信息"""
    results = []
    for day, df in timetable.items():
        # 按实际列位置调整,示例:课程在第2列,时间在第1列,教室在第3列
        match_mask = df.iloc[:, 1] == course_name
        for _, row in df[match_mask].iterrows():
            results.append({
                '日期': day,
                '时间': row.iloc[0],
                '课程': course_name,
                '教室编号': row.iloc[2]
            })
    return pd.DataFrame(results)

def search_course_list(timetable, course_list):
    """查询多门课程的所有场次信息"""
    all_results = []
    for course in course_list:
        course_results = search_single_course(timetable, course.strip())
        all_results.extend(course_results.to_dict('records'))
    return pd.DataFrame(all_results)

def get_free_time_slots(timetable, target_day):
    """获取指定日期的空闲时段"""
    df = timetable[target_day]
    time_col = df.columns[0]
    # 筛选所有课程列都为空的行(课程列从第2列开始)
    free_mask = df.iloc[:, 1:].isna().all(axis=1)
    # 不使用loc,直接用布尔索引+列名
    return df[free_mask][time_col].tolist()

def get_least_used_classroom(timetable):
    """找出整周使用频率最低的教室"""
    room_usage = {}
    for day, df in timetable.items():
        # 假设教室在第3列
        rooms = df.iloc[:, 2].dropna().tolist()
        for room in rooms:
            room_usage[room] = room_usage.get(room, 0) + 1
    min_usage = min(room_usage.values())
    return [room for room, cnt in room_usage.items() if cnt == min_usage]

def get_busiest_lab(timetable):
    """找出整周最繁忙的实验室(假设名称含'Lab')"""
    lab_usage = {}
    for day, df in timetable.items():
        rooms = df.iloc[:, 2].dropna().tolist()
        for room in rooms:
            if 'Lab' in str(room):  # 根据实际实验室命名规则调整
                lab_usage[room] = lab_usage.get(room, 0) + 1
    max_usage = max(lab_usage.values())
    return [lab for lab, cnt in lab_usage.items() if cnt == max_usage]

# 主程序执行
if __name__ == "__main__":
    file_path = r'C:\Users\user\Downloads\TimeTable, FSC, Fall-2022.xlsx'
    timetable = load_and_clean_timetable(file_path)
    
    # 任务3:单课程查询
    single_course = input("请输入要查询的课程名称:").strip()
    print("\n单课程查询结果:")
    print(search_single_course(timetable, single_course))
    
    # 任务4:多课程查询
    course_input = input("\n请输入要查询的课程列表(逗号分隔):").strip()
    course_list = course_input.split(',')
    print("\n多课程查询结果:")
    print(search_course_list(timetable, course_list))
    
    # 任务5:指定日期空闲时段
    target_day = input("\n请输入要查询的日期(如Monday/Tuesday):").strip()
    print(f"\n{target_day}的空闲时段:")
    print(get_free_time_slots(timetable, target_day))
    
    # 任务6:使用频率最低的教室
    print("\n整周使用频率最低的教室:")
    print(get_least_used_classroom(timetable))
    
    # 任务7:最繁忙的实验室
    print("\n整周最繁忙的实验室:")
    print(get_busiest_lab(timetable))

关键注意事项

  • 所有列的位置(课程列、时间列、教室列)需根据你的Excel表实际结构调整,代码中为示例位置
  • 若严格禁用loc,所有筛选操作均使用布尔索引直接操作DataFrame(如df[mask][col])
  • 实验室匹配规则需根据实际命名调整(示例中用'Lab'关键字匹配)

内容的提问来源于stack exchange,提问作者Maryam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 14:15:41