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

Python实现Excel药物不良反应分类宏失败求助

解决Excel药物不良反应分组及格式设置问题(基于Pandas+Openpyxl)

以下是完整可运行的代码,附带关键逻辑说明和常见错误排查:

import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import PatternFill
from openpyxl.utils.dataframe import dataframe_to_rows
import os

# 定义文件路径(兼容多系统)
desktop_path = os.path.expanduser("~/Desktop/Pharm Exam III Drugscopy.xlsx")
# 指定要处理的工作表
target_sheets = ["Antidepressants and Mood", "Immunomodulators", "Drugs of Abuse"]

# 存储不良反应与对应药物的映射
adverse_drug_dict = {}

# 1. 遍历工作表提取并清洗数据
for sheet_name in target_sheets:
    # 仅读取B、D列,提升效率
    df = pd.read_excel(desktop_path, sheet_name=sheet_name, usecols=["B", "D"])
    df.columns = ["Drug_Name", "Adverse_Effects"]
    
    # 提取"-"后内容(兼容"- "格式,仅分割第一个"-")
    df["Cleaned_Adverse"] = df["Adverse_Effects"].apply(
        lambda x: x.split("-", 1)[1].strip() if isinstance(x, str) and "-" in x else ""
    )
    
    # 过滤无效条目
    df = df[df["Cleaned_Adverse"] != ""]
    
    # 填充映射字典,保证药物唯一
    for _, row in df.iterrows():
        adverse = row["Cleaned_Adverse"]
        drug = row["Drug_Name"]
        if adverse not in adverse_drug_dict:
            adverse_drug_dict[adverse] = []
        if drug not in adverse_drug_dict[adverse]:
            adverse_drug_dict[adverse].append(drug)

# 2. 构建输出DataFrame,对齐所有列行数
max_row_count = max(len(drugs) for drugs in adverse_drug_dict.values())
output_data = {}
for adverse, drugs in adverse_drug_dict.items():
    # 用空值填充短列表,避免写入Excel时错位
    output_data[adverse] = drugs + [""] * (max_row_count - len(drugs))
output_df = pd.DataFrame(output_data)

# 3. 写入Excel并设置列颜色
# 加载原工作簿,避免覆盖原始数据
wb = load_workbook(desktop_path)
# 新建汇总表(若已存在则删除)
if "Adverse_Summary" in wb.sheetnames:
    del wb["Adverse_Summary"]
ws = wb.create_sheet("Adverse_Summary")

# 将DataFrame写入工作表
for row_idx, row in enumerate(dataframe_to_rows(output_df, index=False, header=True), 1):
    for col_idx, value in enumerate(row, 1):
        ws.cell(row=row_idx, column=col_idx, value=value)

# 4. 为各列设置不同背景色
# 预设一组填充色(可按需扩展)
fill_colors = [
    "FFE5E5", "E5F2FF", "E5FFE5", "FFF5E5", "F5E5FF",
    "E5FFFF", "FFF0E5", "E5F5FF", "F5FFE5", "FFE5F5"
]
# 遍历列设置颜色(循环使用预设色)
for col_idx, _ in enumerate(output_df.columns, 1):
    fill = PatternFill(
        start_color=fill_colors[(col_idx-1) % len(fill_colors)],
        end_color=fill_colors[(col_idx-1) % len(fill_colors)],
        fill_type="solid"
    )
    # 为表头和所有数据行设置颜色
    for row_idx in range(1, max_row_count + 2):
        ws.cell(row=row_idx, column=col_idx).fill = fill

# 保存为新文件,不覆盖原数据
wb.save(desktop_path.replace(".xlsx", "_processed.xlsx"))
print("处理完成,结果已保存至桌面的_processed.xlsx文件")

关键逻辑说明

  1. 数据清洗:

    • 用split("-",1)仅分割第一个“-”,避免多“-”场景下的错误提取
    • 用strip()去除“- ”后的空格,保证不良反应名称统一
    • 过滤空条目,避免无效数据干扰
  2. 唯一值处理:

    • 通过字典存储映射,写入前判断药物是否已存在,确保每个不良反应下的药物唯一
  3. Excel写入对齐:

    • 找出最长药物列表长度,用空值填充短列表,解决不同列行数不一致导致的错位问题
  4. 样式设置:

    • 循环使用预设颜色,确保列颜色不重复
    • 同时设置表头和数据行的背景色,保证格式统一

常见错误排查

  • 路径错误:直接使用/Desktop/未兼容多系统,代码中用os.path.expanduser解决
  • 字符串处理错误:未处理"- "格式或分割所有“-”,导致不良反应提取错误
  • 重复数据:未判断药物是否已在列表中,导致同一药物重复出现
  • 写入错位:未对齐列行数,导致Excel中数据错位
  • 样式失效:未正确遍历行/列,导致颜色设置未生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:30:27