不规则 Excel“数据提取——教师课表自动汇总实战

今天用一个真实案例,带大家用python实战一下不规则的excel数据,怎么一步一步用 Python 把它"驯服"。


例如下表的excel(20260309.xlsx),结构大致如下:

目标输出:每位老师对应教授了哪些不重复科目,格式如下:

这种表格的挑战在于:每个年级的科目数量不同、表头与年级合并在同一行 ,没有统一的固定格式,无法直接用 pd.read_excel 加表头一步读取。


思路分析

拿到这类"不规则"Excel,核心思路是逐行解析

  1. 遇到"一年级/二年级/三年级"→ 读取该行第2列起的科目名,存入 current_subjects

  2. 遇到含"班"字或"高三"的行 → 按列位置将教师姓名与 current_subjects 对应

  3. defaultdict(set) 存储结果,set 自动去重(同一老师教多个班的同一科目只记录一次)


完整代码解析

1. 数据读取

复制代码
import pandas as pd
from collections import defaultdict

def read_excel_data(file_path):
    """读取Excel文件,返回原始DataFrame"""
    df = pd.read_excel(file_path, header=None)
    return df

使用 header=None 是关键。因为表格没有统一表头行,直接读取全部原始数据,保留每一行的原始结构。


2. 核心解析逻辑

复制代码
def parse_teacher_subject_mapping(df):
    teacher_subject_map = defaultdict(set)
    current_subjects = []

    for _, row in df.iterrows():
        col0 = str(row[0]).strip() if pd.notna(row[0]) else ""
        col1 = str(row[1]).strip() if pd.notna(row[1]) else ""

        # 年级行:同时也是科目表头行
        if col0 in ["一年级", "二年级", "三年级"]:
            current_subjects = []
            for i in range(2, len(row)):
                subject = str(row[i]).strip() if pd.notna(row[i]) else ""
                current_subjects.append(subject)
            continue

        # 班级数据行:含"班"字或为"高三"
        if col1 and ("班" in col1 or col1 == "高三"):
            for i, subject in enumerate(current_subjects):
                col_index = i + 2
                if col_index >= len(row):
                    break
                teacher = str(row[col_index]).strip() if pd.notna(row[col_index]) else ""
                if teacher and teacher != "nan" and subject and subject != "nan":
                    teacher_subject_map[teacher].add(subject)

    return teacher_subject_map

几个细节值得关注:

  • pd.notna() 判空 :Excel 空白单元格读取后是 NaN,必须先判断再 str() 转换,否则会出现字符串 "nan"

  • set 去重 :同一老师在多个班教同一科目,用 set 只记录一次

  • 列位置对齐 :科目从第2列开始,班级数据也从第2列开始,通过 col_index = i + 2 保证对齐


3. 结果格式化与输出

复制代码
def format_result(teacher_subject_map):
    rows = []
    for teacher, subjects in sorted(teacher_subject_map.items()):
        subject_str = ",".join(sorted(subjects))
        rows.append({"老师名字": teacher, "结果": subject_str})
    return pd.DataFrame(rows)

def save_result(result_df, output_path):
    result_df.to_excel(output_path, index=False)

对教师姓名和科目名称都进行了排序(sorted()),让输出结果稳定可预期,而不是依赖字典遍历的随机顺序。

通过上面的代码,就可以完美解决这种问题!!


运行结果

代码总结

技术点 用途
pd.read_excel(header=None) 读取无固定表头的 Excel
pd.notna() 安全处理空白单元格
defaultdict(set) 自动去重的多值映射
iterrows() 逐行遍历,适合结构不规则的数据
sorted() 让输出结果稳定有序

举一反三

这套"逐行解析 + 状态机"的思路,适用于大量现实中的不规则表格场景:

  • 多门店销售汇总:每个门店一个小表头,数据分段存放

  • 项目周报:每周一个标题行,内容逐行展开

  • 混合语言报表:中英文表头混合,列数不固定

核心思路不变:识别"分隔标志行",动态更新当前上下文,逐行提取数据


代码已整理为完整可运行脚本 analyze_teacher_subjects.py,直接放到 Excel 同级目录执行即可。有问题欢迎留言交流!

🔮 获取和交流

阅读原文获取:不规则 Excel"数据提取------教师课表自动汇总实战

相关推荐
Watink Cpper1 小时前
[项目构建]ubuntu24.04下从零部署limap步骤与问题解决方案
python·conda·三维建模·colmap·ubuntu24.04·三维线重建·limap
勿芮介1 小时前
【研发工具】OpenClaw基础环境安装全教程-Node\NVM\PNPM\Bash
开发语言·node.js·bash·ai编程
JamesYoung79711 小时前
第七部分 — 存储 数据建模与迁移提示
java·开发语言·数据结构
进击的雷神1 小时前
无分页一次性加载、多级CSS类名定位、动态User-Agent轮换、断点本地备份——意大利塑料展爬虫四大技术难关攻克纪实
前端·css·爬虫·python
一灰灰blog2 小时前
从零掌握 Spring AI Alibaba Skill:定义、注册与渐进式披露
人工智能·python·spring
大尚来也2 小时前
超越“传参”:HTTP GET与POST的深度辨析与场景选型指南
开发语言
大鹏说大话2 小时前
破局与重构:微服务架构的演进之路、核心挑战与基石组件
开发语言
程序员敲代码吗2 小时前
进程与线程:操作系统中的核心组件
java·开发语言