用python-docx解析霍兰德SDS职业兴趣结果:从docx到可视化报告

📅 发布时间:2026/9/18 15:00:36
用python-docx解析霍兰德SDS职业兴趣结果:从docx到可视化报告
简介这份精品课件以霍兰德SDS职业兴趣测试为对象面向高中生、大学生以及有职业转型需求的职场人士系统性梳理了实际型(R)、研究型(I)、艺术型(A)、社会型(S)、企业型(E)、传统型(C)六类人格类型的共同特征、典型职业方向及相互之间的相邻、相隔关系。文档结合测试量表说明与指导语详细讲解了霍兰德代码如ARS的生成逻辑与解读方法并提出如何判断测试结果是否有效例如蓝色区域呈正六边形或接近正六边形时报告可能无效。同时附有职业索引对照表列出了每类兴趣代码对应的工程师、科学家、作家、咨询人员、律师、会计等具体职业读者可依据自身代码快速查找匹配方向。资源包仅含1个docx文档共145KB内容结构清晰、便于打印与分享目前已有134人学习参考。1. 霍兰德SDS结果文档是档案也是数据如果手里只有一份 docx 格式的霍兰德SDS职业兴趣测试结果你打算拿它做什么绝大多数人第一反应是打开 Word 翻到尾页看结论。但从数据处理角度看这份文档里藏着活动、能力、职业、自我评估等多类分表涉及多个勾选字段和六个维度的分数决定了后续能给出多大范围的倾向性解读。如果你做人力资源、教育咨询或者需要把几十份、上百份结果汇总成可比较的群体画像手动复制粘贴很快就会变成瓶颈。我一般会从解析结构入手把 docx 当作容器而不是一张纸质页。接下来按“读懂结构—编程解析—可视化—写回报告”的顺序把一份普通的结果分析文档变成可复用、可汇总、可继续挖掘的数据资产。2. 先从结果里读懂霍兰德SDSRIASEC维度与计分表结构霍兰德SDS的英文全称是 Self-Directed Search核心是把人格与职业环境映射到六种类型现实型R、研究型I、艺术型A、社会型S、企业型E、常规型C。它不只是给出“你适合什么职业”的结论更看重分数结构和维度组合。大多数人的结果并不是纯粹的单一类型而是三种类型组合也就是常说的三字母代码。比如 RIA 表示现实型、研究型、艺术型相对突出。理解这套逻辑才能定下后面解析代码要抓哪些字段。2.1 霍兰德SDS的六个维度到底在测什么六个维度分别代表不同的兴趣偏好和行为倾向这是后续所有分析的锚点。现实型R偏好在具体任务中动手操作喜欢工具、机械、农林、电气等环境不喜欢过多社交。研究型I享受观察、分析和解决抽象问题常见于科研、数据、实验室场景。艺术型A关注创造、表达和美感写作、设计、音乐、策展都在这个区间。社会型S乐于助人、教授、沟通教师、咨询师、社工是典型代表。企业型E看重影响他人和管理事务销售、经营、法律、政治属于这个维度。常规型C偏爱有序、明确、重复性低变动的任务会计、行政、文档管理都符合。实际解读时不要给某个维度贴“好”或“坏”的标签只能说个体在特定环境中的舒适度不同。SDS 的价值在于把模糊的自我感觉变成可比较的分数所以后面从 docx 里取出来的数字才是真正要保住的信息。2.2 一份结果表里常见的字段和分数来源国内常见的霍兰德SDS结果文档一般由四类分表汇总而来活动、能力、职业、自我评估。每一类里面会有若干条目选中或“是”计 1 分最后按六个维度汇总成总分。有的版本还会额外列出标准分以及建议的职业清单。分表位置常见字段分数含义活动“我喜欢从事……”兴趣倾向判断愿意参与什么活动能力“我能胜任……”自我效能判断认为自己擅长什么职业“我对这些职业感兴趣”职业偏好判断想进入的领域自我评估七个等级打分主观调整用于校正前面三张表的分差不同来源的模板字段名不一定统一常见叫法有“技能”“兴趣程度”“职业偏好”等。解析前必须先把文档里的全部表格打印出来核对列顺序不能想当然地认为第零列一定是 R。2.3 如何根据分数确定三字母职业代码确定三字母代码的基本逻辑很简单把六个维度按分数降序排列取前三个字母。如果出现并列常见做法是保留原表顺序或者按常模顺序取另一种更稳妥的办法是先看分差如果最高分和第二高之间差值小于 3就认为结果不够分化不要硬排三字母。下面是一段最朴素的计算逻辑scores {R: 25, I: 32, A: 18, S: 45, E: 30, C: 22} ranked sorted(scores, keyscores.get, reverseTrue) print(ranked[:3]) # [S, I, E]这段代码先构建一个字典键是维度字母值是分数。sorted按分数降序排列键最后切片取前三个。实际使用时还要考虑并列判据不能只靠原生 list 排序就下结论。理解这一点会对接下来的 docx 解析结果判断有直接帮助因为代码算出的三字母组合错误后面所有职业匹配都会失真。3. 用 python-docx 把霍兰德SDS结果从 docx 里结构化取出来处理 docx 最常见的方式是使用 python-docx 库它不依赖 Word 环境能在 Linux、Windows、macOS 上统一运行。你不需要把结果手动录入到 Excel直接用程序遍历文档中的段落和表格再把分数行组织成结构化数据。3.1 安装依赖和读取 docx 的两种常用用法先装依赖我一般会用 pip 安装四个库pip install python-docx pandas openpyxl matplotlibpython-docx 负责读取和生成 Wordpandas 做表格整理openpyxl 用于导出和二次加工matplotlib 负责后面画图。安装完成后写一个最小读取脚本from docx import Document doc Document(SDS结果分析.docx) print(--- 段落 ---) for p in doc.paragraphs: if p.text.strip(): print(p.text) print(--- 表格数量 ---) print(len(doc.tables))这段代码会先打印文档里所有非空段落再输出表格总数。为什么先看段落因为很多 docx 的结果文档里结论和注意事项都在段落里而分数明细在表格里。直接跳去解析表格容易漏掉“测评日期”“姓名”这类关键上下文信息。3.2 遍历表格定位 RIASEC 分数行拿到总表数后你需要把每个表格的行列结构打出来看。不同版本的SDS结果 docx 可能只有一个总表也可能每个分表独立甚至表格里嵌套表格。下面这段代码会列出所有表格的单元格内容for i, table in enumerate(doc.tables): print(f----- 表格 {i} -----) for row in table.rows: cells [cell.text.strip() for cell in row.cells] print(cells)table.rows遍历每一行row.cells返回该行所有单元格对象.text.strip()去掉首尾空格。运行后你会看到类似[R, 25]或[现实型, 25, 研究型, 32]的结构。有些模板会把标题放在一个单元格里这时候不能按固定位置下结论而要在表头里先定位“R、I、A、S、E、C”六个字母所在列再把这个表头区域作为解析锚点。3.3 清洗中文数字与特殊字符生成 DataFrame实际从 docx 里读到的单元格文本经常混着空格、全角数字、单位甚至“25分”这种带后缀的写法。我一般会用正则只提取带正负号或小数的数字再做类型转换import re import pandas as pd def extract_number(value): nums re.findall(r-?\d\.?\d*, value) return float(nums[0]) if nums else 0.0 def parse_riasec_row(row): scores [] for cell in row.cells: scores.append(extract_number(cell.text)) return scores row_scores [53, 41, 35, 48, 38, 29] df pd.DataFrame( [row_scores], columns[R, I, A, S, E, C] ) print(df)这里的extract_number用正则从25分、 32 、35.0一类文本中提取第一个可识别数字。parse_riasec_row把一行单元格转成数字列表。如果某个单元格没有数字就填 0.0避免因为格式缺位导致整行解析失败。最终生成的df就是一个标准的 RIASEC 分数矩50阵后面做绘图和匹配时可以直接用 pandas 的列名取值。4. 画霍兰德六边形雷达图让结果一眼可读分数只存在于表格里还不够把六个维度视觉化成六边形雷达图才能让被试者一眼看出自己的优势区间。霍兰德的理论模型是一个六边形相邻维度距离近对角维度距离远所以画图时保留六边形方位比普通柱状图更有解释力。4.1 六边形角度布局与坐标映射把六个维度均匀放在圆周上R 放在正上方或右侧都行关键是相邻顺序固定为 R-I-A-S-E-C因为在霍兰德六边形中相邻关系代表相近的心理特征。如果顺序错乱图形形状会严重误导读者。角度计算使用极坐标import numpy as np labels [R, I, A, S, E, C] angles np.linspace(0, 2 * np.pi, len(labels), endpointFalse).tolist() print(angles)np.linspace(0, 2 * np.pi, len(labels), endpointFalse)会均匀生成 6 个角度值最后一个点不与首点重合。这样六个点平均分布在圆周上得到的六边形才是等边的。4.2 用 matplotlib 画 RIASEC 雷达图和柱状图matplotlib 的polar投影很适合画雷达图。要注意雷达图必须把首尾闭合否则图像会有缺口。下面是一个完整绘图示例import matplotlib.pyplot as plt values [53, 41, 35, 48, 38, 29] angles_closed angles angles[:1] values_closed values values[:1] fig, ax plt.subplots(figsize(6, 6), subplot_kw{projection: polar}) ax.plot(angles_closed, values_closed, o-, linewidth2) ax.fill(angles_closed, values_closed, alpha0.25) ax.set_xticks(angles) ax.set_xticklabels(labels) ax.set_ylim(0, max(values) 10) plt.show()values_closed把第一个值重复放到最后让多边形闭合。ax.fill填充区域alpha 控制透明度方便观察重叠。set_ylim留出顶部余量避免最高分贴边。实际保存时建议用plt.savefig(riasec.png, dpi300)保证报告里图片清晰。4.3 用向量计算度量与常模职业代码的匹配度雷达图只能展示个人形态想要把结果推荐给职业库还需要做一个匹配计算。常见做法是把个人六个维度分数看作一个向量用余弦相似度衡量与典型职业代码向量之间的接近程度。举个例子RIASEC 可以映射为六维向量然后用余弦公式计算import math def cosine_similarity(a, b): dot sum(x * y for x, y in zip(a, b)) norm_a math.sqrt(sum(x ** 2 for x in a)) norm_b math.sqrt(sum(y ** 2 for y in b)) if norm_a 0 or norm_b 0: return 0.0 return dot / (norm_a * norm_b) user_vec [53, 41, 35, 48, 38, 29] typical_vec [50, 45, 30, 40, 35, 25] print(round(cosine_similarity(user_vec, typical_vec), 3))cosine_similarity返回一个 0 到 1 之间的相似度值越接近 1 就说明个人兴趣结构与这个职业代码越一致。使用时要特别注意典型职业向量需要从常模或已知样例中构造可以用“某职业从业者平均得分”作为基准。5. 自动生成霍兰德SDS分析报告记录结果而不是只解释分析不能停留在个人电脑里的图表上把雷达图、计算表、三字母代码一起整理成一份可导出的报告才能交付给咨询者或归档到测评系统。用 python-docx 可以把刚才生成的图片和结构化分数写入一份新 docx。5.1 一个脚本把图片和统计表塞进 docx 报告下面的代码演示如何用 python-docx 生成一份包含标题、图片、表格的最简报告from docx import Document from docx.shared import Inches report Document() report.add_heading(霍兰德SDS职业兴趣测试分析报告, 0) report.add_heading(一、六维度原始分, level1) score_table report.add_table(rows2, cols6) score_table.style Table Grid for i, col in enumerate(labels): score_table.rows[0].cells[i].text col score_table.rows[1].cells[i].text str(values[i]) report.add_heading(二、雷达图, level1) report.add_picture(riasec.png, widthInches(5.5)) report.save(分析报告.docx)add_heading的第二个参数控制标题级别0 是文章主标题add_table(rows2, cols6)创建了一个 2 行 6 列的表格Table Grid样式会显示边框线。add_picture负责插入图片widthInches(5.5)将图片宽度限制在页面可打印范围内。5.2 导出 Excel 备查表方便批量汇总需要批量处理多份 docx 时把结果统一追加到一个 DataFrame再调用to_excel导出效率会高很多df_all pd.DataFrame([ {姓名: 张三, R: 53, I: 41, A: 35, S: 48, E: 38, C: 29}, {姓名: 李四, R: 22, I: 39, A: 44, S: 50, E: 30, C: 25}, ]) df_all.to_excel(SDS汇总表.xlsx, indexFalse)indexFalse用来避免把 pandas 自动生成的DataFrame下标写进文件。Excel 输出可以保留更多原始分数方便之后做群体常模、对比分析。5.3 一个容易踩的坑检查列顺序与文本混排解析时最常出的问题不是代码逻辑不对而是源 docx 的表格列顺序不固定。有些模板把“现实型”和“R”放在不同单元格有些则直接使用“R型”作为表头。我的建议是解析前先读取第一行判断六个维度字母是否完整出现只要缺失或顺序异常立即中止解析并输出警告。这样处理完之后你拿到的不只是一份 docx 的解析结果而是一套可以反复使用的流程从文档读取、清洗、可视化到生成报告整套逻辑都可以复制到其他年份或模板的SDS结果中。本文还有配套的精品资源点击获取