Files
AIclinicalresearch/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_功能按钮开发计划_V1.0.md
HaHafeng 74cf346453 feat(dc/tool-c): Add missing value imputation feature with 6 methods and MICE
Major features:
1. Missing value imputation (6 simple methods + MICE):
   - Mean/Median/Mode/Constant imputation
   - Forward fill (ffill) and Backward fill (bfill) for time series
   - MICE multivariate imputation (in progress, shape issue to fix)

2. Auto precision detection:
   - Automatically match decimal places of original data
   - Prevent false precision (e.g. 13.57 instead of 13.566716417910449)

3. Categorical variable detection:
   - Auto-detect and skip categorical columns in MICE
   - Show warnings for unsuitable columns
   - Suggest mode imputation for categorical data

4. UI improvements:
   - Rename button: "Delete Missing" to "Missing Value Handling"
   - Remove standalone "Dedup" and "MICE" buttons
   - 3-tab dialog: Delete / Fill / Advanced Fill
   - Display column statistics and recommended methods
   - Extended warning messages (8 seconds for skipped columns)

5. Bug fixes:
   - Fix sessionService.updateSessionData -> saveProcessedData
   - Fix OperationResult interface (add message and stats)
   - Fix Toolbar button labels and removal

Modified files:
Python: operations/fillna.py (new, 556 lines), main.py (3 new endpoints)
Backend: QuickActionService.ts, QuickActionController.ts, routes/index.ts
Frontend: MissingValueDialog.tsx (new, 437 lines), Toolbar.tsx, index.tsx
Tests: test_fillna_operations.py (774 lines), test scripts and docs
Docs: 5 documentation files updated

Known issues:
- MICE imputation has DataFrame shape mismatch issue (under debugging)
- Workaround: Use 6 simple imputation methods first

Status: Development complete, MICE debugging in progress
Lines added: ~2000 lines across 3 tiers
2025-12-10 13:06:00 +08:00

35 KiB
Raw Blame History

工具C 功能按钮开发计划 V1.0

文档版本: V1.4 (Phase 2+ 缺失值填补功能开发版)
创建日期: 2025-12-08
最后更新: 2025-12-10
负责人: AI开发团队
项目状态: Phase 1-2 已完成7个核心功能 + NA处理优化 + Pivot优化 + 缺失值填补开发完成MICE待调试


🔥 重要架构变更2025-12-08

决策:功能按钮采用预写Python函数架构,而非动态代码生成。

变更原因

  • 旧方案动态拼接Python代码字符串 → 不稳定、有安全风险、难以测试
  • 新方案调用预写的Python函数 → 稳定、安全、高性能、易维护

当前完成2025-12-08

  • Python微服务operations/ 模块
    • filter.py高级筛选
    • recode.py数值映射
    • binning.py生成分类变量
    • conditional.py条件生成列
    • dropna.py删除缺失值
    • compute.py计算列
    • pivot.py长表转宽表
  • Python微服务7个API端点/api/operations/*
  • Node.js后端QuickActionService.ts7个执行方法
  • Node.js后端QuickActionController.ts(完整错误处理)
  • 前端UI7个Dialog组件完整交互界面
  • 前端工具栏7个功能按钮已启用
  • 删除:QuickActionCodeGenerator.ts(不再使用)

架构对比

维度 旧方案 新方案
稳定性 ⚠️ 字符串拼接易出错 预写函数经过测试
安全性 ⚠️ 有注入风险 无代码注入风险
性能 ⚠️ 需解析代码 直接调用函数
可维护 ⚠️ 后端拼接字符串 Python集中管理
可测试 难以测试 易于单元测试

📋 文档目录


1. 概述

1.1 背景

工具C当前已实现AI对话式数据清洗功能。为提升用户体验和操作效率需要针对高频、通用、标准化的数据清洗操作开发功能按钮,实现一键式操作

1.2 目标

  • 提升高频操作的效率(从"描述需求"到"一键点击"
  • 降低学习成本直观的UI代替自然语言描述
  • 保持灵活性复杂需求仍可使用AI对话
  • 符合医疗科研用户习惯参考SPSS、Excel等专业工具

1.3 适用场景

功能按钮适合:

  • 高频使用(每个数据集都需要)
  • 操作通用(不依赖特定业务规则)
  • 参数明确可以通过UI配置
  • 逻辑简单1-3步即可完成

AI对话适合

  • 低频使用(偶尔用一次)
  • 业务特定(规则各异)
  • 复杂逻辑(多步骤、多条件)
  • 探索性操作(需理解上下文)

2. 设计原则

2.1 用户体验原则

  1. 80/20法则用按钮解决80%的简单需求用AI对话解决20%的复杂需求
  2. 渐进式披露:简单功能默认显示,复杂选项折叠/高级模式
  3. 即时反馈:提供预览功能,让用户在执行前看到结果
  4. 可撤销性:支持撤销(未来版本)或提供"创建副本"选项

2.2 技术原则

  1. 预写函数架构功能按钮调用预写的、经过测试的Python函数而非动态生成代码
  2. 无状态设计:每个操作独立,不依赖前序状态
  3. 安全可靠:预写函数经过充分测试和验证,无代码注入风险
  4. 性能优先:直接调用函数,避免代码解析开销,优化大数据集处理

3. 功能清单

3.1 按分组划分

分组 功能 优先级 开发状态
样本筛选 高级筛选器 P0 已完成(+为空/不为空条件)
变量转换 数值映射(重编码) P0 已完成(+NA处理选项
生成分类变量(分箱) P0 已完成(+NA处理选项
条件生成列 P0 已完成(+为空/不为空条件)
生成新变量(计算列) P1 已完成方案B安全列名映射
数据清理 缺失值处理(删除+填补) P0 已完成6种简单填补+MICEMICE待调试
去重 P1 ⏸️ 已移除(用户需求)
数据重塑 长表→宽表Pivot P1 已完成(+保留未选列+原始列顺序)
高级功能 多重插补MICE P0 🚧 已集成到缺失值处理(待调试)

优先级说明

  • P0核心功能Phase 1-2 必须完成
  • P1重要功能Phase 3 完成
  • P2增强功能Phase 4 可选

3.2 不开发的功能

功能 原因
清理列名 暂不开发(用户需求)
宽表→长表 低频需求,暂不开发
数据透视表 超出MVP范围
统计分析 属于统计分析模块,非数据清洗

4. 分期开发计划

Phase 1核心功能Week 1预计5天 已完成

目标解决最高频的3个需求

功能 工作量 状态 验收标准
1. 高级筛选器 2天 完成 支持多条件AND/OR实时预览
2. 数值映射(重编码) 1.5天 完成 自动提取唯一值,支持批量映射
3. 生成分类变量(分箱) 1.5天 完成 支持自定义切点、等宽、等频

里程碑 Week 1完成3个核心功能可用2025-12-08


Phase 2条件生成+清理Week 2预计5天 已完成

目标:解决复杂条件逻辑需求

功能 工作量 状态 验收标准
4. 条件生成列 2天 完成 支持多条件IF-THEN规则
5. 删除缺失值 1天 完成 支持按行/列删除,预览影响
6. 去重 1天 ⏸️ 暂不开发 用户决定暂不开发
7. 计算列 1天 完成 公式构建器,支持常用函数
8. Pivot长→宽表 1天 完成 支持多值列转换,聚合选项

里程碑 Week 2完成7个核心功能可用2025-12-08


Phase 3数据重塑+填补Week 3-4预计8天

目标:支持复杂数据转换

功能 工作量 负责人 验收标准
8. 长表→宽表Pivot 2天 前端+后端 支持多值列转换
9. 生成新变量(计算列) 2天 前端+后端 公式构建器,支持常用函数
10. 缺失值填补 1.5天 前端+后端 支持均值/中位数/分组填补
11. 多重插补MICE 1.5天 Python微服务 集成sklearn支持基础MICE
12. 测试+文档 1天 全员 完成用户手册

里程碑Week 4结束所有P0/P1功能完成


Phase 4优化+增强Week 5+,持续迭代)

  • 性能优化(大数据集>10万行
  • 批量操作(批量重编码、批量删除列等)
  • 操作历史(查看/回退历史操作)
  • 保存为模板(常用操作保存为快捷方式)
  • 数据验证(自动检查数据质量)

5. 技术架构

5.1 整体架构(预写函数方案)

架构决策:功能按钮使用预写Python函数,而非动态生成代码,确保稳定性和性能。

┌─────────────────────────────────────────────────┐
│  前端 (React + Ant Design)                      │
│  ┌─────────────────────────────────────────┐   │
│  │  工具栏组件                              │   │
│  │  ┌────┐ ┌────┐ ┌────┐ ┌────┐           │   │
│  │  │筛选│ │重编│ │分箱│ │条件│  ...      │   │
│  │  └────┘ └────┘ └────┘ └────┘           │   │
│  └─────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────┐   │
│  │  配置对话框(各功能独立)                │   │
│  │  - 参数输入                              │   │
│  │  - 实时预览                              │   │
│  │  - 执行按钮                              │   │
│  └─────────────────────────────────────────┘   │
└────────────────────┬────────────────────────────┘
                     │ HTTP POST
                     ↓
┌─────────────────────────────────────────────────┐
│  后端 (Node.js + Fastify)                       │
│  ┌─────────────────────────────────────────┐   │
│  │  QuickActionController                   │   │
│  │  - 接收功能按钮请求                      │   │
│  │  - 验证参数                              │   │
│  │  - 调用QuickActionService                │   │
│  └─────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────┐   │
│  │  ✅ QuickActionService (新)             │   │
│  │  - executeFilter()   调用预写函数API     │   │
│  │  - executeRecode()   调用预写函数API     │   │
│  │  - executeBinning()  调用预写函数API     │   │
│  └─────────────────────────────────────────┘   │
└────────────────────┬────────────────────────────┘
                     │ HTTP POST /api/operations/xxx
                     ↓
┌─────────────────────────────────────────────────┐
│  Python微服务 (FastAPI)                         │
│  ┌─────────────────────────────────────────┐   │
│  │  ✅ operations/ (预写函数模块)          │   │
│  │  - filter.py      (筛选)                 │   │
│  │  - recode.py      (重编码)               │   │
│  │  - binning.py     (分箱)                 │   │
│  │  - conditional.py (条件生成,待开发)     │   │
│  │  - missing.py     (缺失值处理,待开发)   │   │
│  │  每个函数:                              │   │
│  │    ✓ 经过单元测试                        │   │
│  │    ✓ 有完整类型注解                      │   │
│  │    ✓ 有详细文档                          │   │
│  └─────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────┐   │
│  │  ✅ API端点 (新)                        │   │
│  │  POST /api/operations/filter             │   │
│  │  POST /api/operations/recode             │   │
│  │  POST /api/operations/binning            │   │
│  └─────────────────────────────────────────┘   │
└─────────────────────────────────────────────────┘

优势

  • 稳定性高:预写函数经过单元测试,无字符串拼接风险
  • 性能好:直接调用函数,无代码解析开销
  • 可维护代码集中在Python侧便于优化
  • 安全:无代码注入风险

已废弃

  • QuickActionCodeGenerator.ts (已删除)
  • 动态代码生成方案 (已弃用)

5.2 API设计重构后

Node.js后端API前端调用

// 执行快速操作
POST /api/v1/dc/tool-c/quick-action
Body: {
  sessionId: string,
  action: 'filter' | 'recode' | 'binning' | 'conditional' | ...,
  params: {
    // 各功能特定参数
  }
}
Response: {
  success: boolean,
  data: {
    newDataPreview: Array<Object>,  // 前50行预览
    affectedRows: number,           // 影响的行数
    message: string,                // 操作说明
    executionTime: number,          // Python执行时间
    output: string                  // Python打印输出
  }
}

// 预览操作结果(不实际执行)
POST /api/v1/dc/tool-c/quick-action/preview
Body: { 同上 }
Response: {
  success: boolean,
  data: {
    preview: Array<Object>,         // 前10行预览
    estimatedChange: string,        // "将删除23行" / "将新增1列"
    originalRows: number,
    newRows: number
  }
}

Python微服务API后端调用新增

注意以下URL仅为示例实际代码中使用环境变量 EXTRACTION_SERVICE_URL 配置。

# 高级筛选示例URL
POST http://localhost:8000/api/operations/filter
Body: {
  "data": [{"年龄": 25, "性别": "男"}, ...],
  "conditions": [
    {"column": "年龄", "operator": ">", "value": 30},
    {"column": "性别", "operator": "=", "value": "男"}
  ],
  "logic": "and"  # or "or"
}
Response: {
  "success": true,
  "result_data": [...],  # 筛选后的数据
  "output": "原始数据: 100 行\n筛选后: 30 行...",
  "execution_time": 0.023,
  "result_shape": [30, 5]
}

# 数值映射(重编码)
POST http://localhost:8000/api/operations/recode
Body: {
  "data": [{"性别": "男"}, {"性别": "女"}, ...],
  "column": "性别",
  "mapping": {"男": 1, "女": 2},
  "create_new_column": true,
  "new_column_name": "性别_编码"
}
Response: {
  "success": true,
  "result_data": [...],
  "output": "映射完成: 96 个值成功映射\n映射成功率: 100.0%",
  "execution_time": 0.015,
  "result_shape": [96, 6]
}

# 生成分类变量(分箱)
POST http://localhost:8000/api/operations/binning
Body: {
  "data": [{"年龄": 25}, {"年龄": 35}, ...],
  "column": "年龄",
  "method": "custom",  # or "equal_width", "equal_freq"
  "new_column_name": "年龄分组",
  "bins": [18, 60],  # 自定义切点
  "labels": ["青少年", "成年", "老年"]
}
Response: {
  "success": true,
  "result_data": [...],
  "output": "分箱结果分布:\n  青少年: 10 行 (10.4%)\n  成年: 70 行 (72.9%)...",
  "execution_time": 0.018,
  "result_shape": [96, 6]
}

5.3 预写函数服务设计(重构后)

Node.js后端服务

// backend/src/modules/dc/tool-c/services/QuickActionService.ts

export class QuickActionService {
  
  // 调用Python微服务的预写函数API
  async executeFilter(data: any[], params: FilterParams): Promise<OperationResult> {
    return axios.post(`${PYTHON_SERVICE_URL}/api/operations/filter`, {
      data,
      conditions: params.conditions,
      logic: params.logic,
    });
  }
  
  async executeRecode(data: any[], params: RecodeParams): Promise<OperationResult> {
    return axios.post(`${PYTHON_SERVICE_URL}/api/operations/recode`, {
      data,
      column: params.column,
      mapping: params.mapping,
      create_new_column: params.createNewColumn,
      new_column_name: params.newColumnName,
    });
  }
  
  async executeBinning(data: any[], params: BinningParams): Promise<OperationResult> {
    return axios.post(`${PYTHON_SERVICE_URL}/api/operations/binning`, {
      data,
      column: params.column,
      method: params.method,
      new_column_name: params.newColumnName,
      bins: params.bins,
      labels: params.labels,
      num_bins: params.numBins,
    });
  }
}

Python预写函数

# extraction_service/operations/filter.py
def apply_filter(df: pd.DataFrame, conditions: List[Dict], logic: str) -> pd.DataFrame:
    """
    应用筛选条件(预写函数,经过充分测试)
    
    Args:
        df: 输入数据框
        conditions: 筛选条件列表
        logic: 'and' 或 'or'
    
    Returns:
        筛选后的数据框
    """
    # 生成各个条件的mask
    masks = []
    for cond in conditions:
        column = cond['column']
        operator = cond['operator']
        value = cond.get('value')
        
        if operator == '=':
            mask = df[column] == value
        elif operator == '>':
            mask = df[column] > value
        # ... 其他运算符
        
        masks.append(mask)
    
    # 组合条件
    if logic == 'and':
        final_mask = pd.concat(masks, axis=1).all(axis=1)
    else:
        final_mask = pd.concat(masks, axis=1).any(axis=1)
    
    return df[final_mask].copy()

# extraction_service/main.py
@app.post("/api/operations/filter")
async def operation_filter(request: FilterRequest):
    """调用预写函数"""
    df = pd.DataFrame(request.data)
    result_df = apply_filter(df, request.conditions, request.logic)
    return JSONResponse(content={
        "success": True,
        "result_data": result_df.to_dict('records'),
        "execution_time": execution_time,
        ...
    })

优势

  • 预写函数经过单元测试,稳定可靠
  • 无字符串拼接,无代码注入风险
  • 直接调用函数,性能优秀
  • 代码集中管理,易于维护和优化

已废弃

  • QuickActionCodeGenerator.ts (已删除,不再使用动态代码生成)

5.4 环境变量配置

重要代码中使用环境变量配置Python微服务地址不使用硬编码

Node.js后端配置

backend/.env 中配置:

# Python微服务地址必需
EXTRACTION_SERVICE_URL=http://localhost:8000

# 生产环境示例
# EXTRACTION_SERVICE_URL=http://python-service:8000
# EXTRACTION_SERVICE_URL=https://api.yourdomain.com/python

代码实现

// backend/src/modules/dc/tool-c/services/QuickActionService.ts
const PYTHON_SERVICE_URL = process.env.EXTRACTION_SERVICE_URL || 'http://localhost:8000';

// 调用时使用环境变量
await axios.post(`${PYTHON_SERVICE_URL}/api/operations/filter`, {...});

优势

  • 开发环境:使用 localhost:8000
  • 生产环境:使用内网地址或域名
  • 容器化部署:使用服务名(如 http://python-service:8000
  • 符合云原生开发规范

6. 详细设计

6.1 高级筛选器

UI设计

┌─────────────────────────────────────────┐
│  高级筛选                                │
├─────────────────────────────────────────┤
│  ┌─────────────────────────────────────┐│
│  │ [列名 ▼] [条件 ▼] [值_________]    ││
│  └─────────────────────────────────────┘│
│  [且 ▼]                                 │
│  ┌─────────────────────────────────────┐│
│  │ [列名 ▼] [条件 ▼] [值_________]    ││
│  └─────────────────────────────────────┘│
│  [+ 添加条件]                           │
│                                         │
│  预览:将保留 87 行共100行          │
│                                         │
│  [取消]  [预览]  [应用]                │
└─────────────────────────────────────────┘

条件运算符

  • 数值列:=, , >, <, ,
  • 文本列:等于, 不等于, 包含, 不包含, 以...开头, 以...结尾
  • 通用:为空, 不为空

生成代码示例

# 单条件
df = df[df['年龄'] >= 18]

# 多条件 AND
df = df[(df['年龄'] >= 18) & (df['性别'] == '男')]

# 多条件 OR
df = df[(df['年龄'] >= 60) | (df['BMI'] >= 28)]

# 包含
df = df[df['诊断'].str.contains('糖尿病', na=False)]

# 不为空
df = df[df['BMI'].notna()]

6.2 数值映射(重编码)

UI设计

┌─────────────────────────────────────┐
│  变量重编码                          │
├─────────────────────────────────────┤
│  选择列:[研究中心 ▼]               │
│                                     │
│  自动检测到 3 个唯一值:            │
│  ┌─────────────────┬─────────────┐ │
│  │ 原值            │ 新值        │ │
│  ├─────────────────┼─────────────┤ │
│  │ 黑龙江中医药... │ [1______]   │ │
│  │ 山东中医药...   │ [2______]   │ │
│  │ 广州中医药...   │ [3______]   │ │
│  └─────────────────┴─────────────┘ │
│                                     │
│  ☑️ 创建新列(推荐)                │
│  新列名:[研究中心_编码_______]     │
│                                     │
│  [取消]  [预览]  [执行]            │
└─────────────────────────────────────┘

生成代码示例

# 创建新列
mapping = {
  '黑龙江中医药大学附属第二医院': 1,
  '山东中医药大学附属医院': 2,
  '广州中医药大学附属第一医院': 3
}
df['研究中心_编码'] = df['研究中心'].map(mapping)

# 或覆盖原列
df['研究中心'] = df['研究中心'].map(mapping)

6.3 生成分类变量(分箱)

UI设计

┌─────────────────────────────────────┐
│  连续变量分箱                        │
├─────────────────────────────────────┤
│  选择数值列:[督脉针刺持续时间 ▼]   │
│                                     │
│  分箱方式:                         │
│  ● 自定义切点                       │
│     切点:[10] [+]                 │
│     标签:                         │
│       ≥10: [暴露=1_____]          │
│       <10: [非暴露=0___]          │
│                                     │
│  ○ 多段切点                         │
│     切点:[0] [14] [30] [999]      │
│     标签:[低=0][中=1][高=2]       │
│                                     │
│  新列名:[住院患者暴露分组_____]    │
│                                     │
│  [取消]  [预览分布]  [执行]        │
└─────────────────────────────────────┘

生成代码示例

# 二分类(单切点)
df['住院患者暴露分组'] = (df['督脉针刺持续时间'] >= 10).astype(int)

# 多分类(多切点)
df['暴露强度分组'] = pd.cut(
    df['督脉针刺持续时间'],
    bins=[0, 14, 30, 999],
    labels=[0, 1, 2],
    right=False
)

6.4 条件生成列 核心功能

UI设计

┌─────────────────────────────────────────┐
│  条件生成新列                            │
├─────────────────────────────────────────┤
│  新列名:[住院暴露出院暴露情况分组____] │
│                                         │
│  规则(按顺序匹配):                    │
│  ┌───────────────────────────────────┐ │
│  │ 规则1                             │ │
│  │ IF [住院患者暴露分组▼] [=▼] [1]  │ │
│  │ [且▼]                            │ │
│  │ IF [督脉针刺持续时间▼] [>=▼][14] │ │
│  │ THEN 值为:[住院暴露出院暴露____] │ │
│  │                          [删除规则]│ │
│  └───────────────────────────────────┘ │
│  ┌───────────────────────────────────┐ │
│  │ 规则2                             │ │
│  │ IF [住院患者暴露分组▼] [=▼] [1]  │ │
│  │ [且▼]                            │ │
│  │ IF [督脉针刺持续时间▼] [<▼] [14] │ │
│  │ THEN 值为:[住院暴露出院非暴露__] │ │
│  │                          [删除规则]│ │
│  └───────────────────────────────────┘ │
│  [+ 添加规则]                          │
│                                         │
│  其他情况ELSE                     │
│  ● 留空None                        │
│  ○ 固定值:[_______]                  │
│  ○ 使用默认值:[0______]              │
│                                         │
│  预览将生成新列预计87行有值         │
│                                         │
│  [取消]  [预览前10行]  [执行]          │
└─────────────────────────────────────────┘

技术实现

前端数据结构

interface ConditionalRule {
  conditions: Array<{
    column: string,
    operator: '=' | '!=' | '>' | '<' | '>=' | '<=',
    value: string | number
  }>,
  logic: 'and' | 'or',
  result: string | number
}

interface ConditionalParams {
  newColumnName: string,
  rules: ConditionalRule[],
  elseValue: null | string | number
}

生成代码示例

def classify_exposure(row):
    # 规则1
    if row['住院患者暴露分组'] == 1 and row['督脉针刺持续时间'] >= 14:
        return '住院暴露出院暴露'
    # 规则2
    elif row['住院患者暴露分组'] == 1 and row['督脉针刺持续时间'] < 14:
        return '住院暴露出院非暴露'
    # ELSE
    else:
        return None

df['住院暴露出院暴露情况分组'] = df.apply(classify_exposure, axis=1)

6.5 长表→宽表Pivot

UI设计

┌─────────────────────────────────────┐
│  长表转宽表Pivot                 │
├─────────────────────────────────────┤
│  索引列(唯一标识):                │
│  [Record ID ▼]                      │
│                                     │
│  透视列(变成列名):                │
│  [Event Name ▼]                     │
│  检测到的值:                       │
│  • 筛选及基线                       │
│  • 随访2周                      │
│  • 随访1个月                    │
│                                     │
│  值列(要转置的数据):              │
│  ☑️ FMA总得分                       │
│  ☑️ FMA分级(1-5)                    │
│  ☑️ ADL总分                         │
│  ☑️ NLR                             │
│  ☑️ PLR                             │
│  [ ] ...(选择其他列)              │
│                                     │
│  重复值处理:                       │
│  ● 取第一个  ○ 取最后一个          │
│  ○ 求平均值  ○ 求和                │
│                                     │
│  [取消]  [预览结构]  [执行]        │
└─────────────────────────────────────┘

生成代码示例

# Pivot转换
df_pivot = df.pivot_table(
    index='Record ID',
    columns='Event Name',
    values=['FMA总得分', 'FMA分级(1-5)', 'ADL总分', 'NLR', 'PLR'],
    aggfunc='first'
)

# 展平多级列名
df_pivot.columns = ['_'.join(col).strip() for col in df_pivot.columns.values]
df_pivot = df_pivot.reset_index()

# 示例FMA总得分_筛选及基线, FMA总得分_随访(2周)

6.6 多重插补MICE

UI设计

┌─────────────────────────────────────┐
│  多重插补MICE                    │
├─────────────────────────────────────┤
│  ⚠️ 高级统计功能,需谨慎使用        │
│                                     │
│  选择需要插补的列:                 │
│  ☑️ 年龄                           │
│  ☑️ BMI                            │
│  ☑️ 血糖                           │
│  [ ] 血压                          │
│  [ ] ...                           │
│                                     │
│  参数设置:                         │
│  迭代次数:[10____]推荐5-20    │
│  随机种子:[42____](可重复结果)  │
│                                     │
│  预计插补32个缺失值               │
│                                     │
│  ⚠️ 注意:                         │
│  • MICE假设数据MAR随机缺失     │
│  • 插补时间较长(大数据集>1分钟  │
│  • 建议先备份原数据                │
│                                     │
│  [取消]  [执行]                    │
└─────────────────────────────────────┘

技术实现

依赖库需在Python微服务中安装 scikit-learn

from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

# 选择需要插补的列
cols_to_impute = ['年龄', 'BMI', '血糖']
df_subset = df[cols_to_impute]

# MICE插补
imputer = IterativeImputer(
    max_iter=10,
    random_state=42,
    verbose=0
)
df[cols_to_impute] = imputer.fit_transform(df_subset)

print(f'插补完成,剩余缺失值: {df[cols_to_impute].isna().sum().sum()}')

7. 验收标准

7.1 功能验收

每个功能按钮需通过以下测试:

基础功能测试

测试项 验收标准
UI显示 按钮、对话框正确渲染,无布局错误
参数验证 错误输入有友好提示
预览功能 预览结果准确,性能<2秒
执行功能 代码正确执行,结果符合预期
错误处理 异常有明确提示,不崩溃

数据准确性测试

测试项 验收标准
小数据集 <1000行结果100%准确
中数据集 1000-10000行性能<5秒
大数据集 10000-50000行性能<30秒
边界情况 全空列、全0列、单行等正确处理

用户体验测试

测试项 验收标准
学习成本 新用户5分钟内学会使用
操作效率 比AI对话快3-5倍
错误恢复 支持撤销或提供"创建副本"选项

7.2 性能基准

操作 数据量 目标性能
高级筛选 10万行 <2秒
数值映射 10万行 <3秒
分箱 10万行 <3秒
条件生成列 10万行 <5秒
Pivot转换 5000行 <10秒
MICE插补 5000行 <60秒

7.3 代码质量标准

  • 代码覆盖率 >80%
  • ESLint/TSLint 0错误
  • 所有API有完整的TypeScript类型定义
  • 关键函数有JSDoc注释
  • 用户操作有日志记录

8. 风险评估

8.1 技术风险

风险 影响 概率 应对措施
Python库依赖问题 提前验证库兼容性
大数据集性能 分批处理+进度条
代码生成错误 严格单元测试
浏览器兼容性 只支持现代浏览器

8.2 用户体验风险

风险 影响 概率 应对措施
功能过于复杂 提供视频教程
与AI功能冲突 明确使用场景
期望过高 明确功能边界

9. 后续规划

Phase 5智能化增强2-3个月后

  1. 操作推荐:根据数据特征推荐合适的操作
  2. 自动诊断:检测数据质量问题(缺失、异常、重复)
  3. 批量操作:一次性应用多个操作
  4. 操作模板:保存常用操作序列

Phase 6协作增强3-6个月后

  1. 操作历史:查看、回退、分享操作历史
  2. 团队模板:团队共享清洗模板
  3. 数据版本:支持数据快照和版本管理

10. 附录

10.1 参考资料

  • SPSS数据清洗功能
  • Excel数据透视表
  • Python Pandas文档
  • Ant Design组件库

10.2 术语表

术语 解释
重编码 将一列的值映射为另一组值
分箱 将连续数值转为离散分类
Pivot 长表转宽表的数据重塑操作
MICE 多重插补法,处理缺失值的统计方法
MAR Missing At Random随机缺失

10.3 更新日志

版本 日期 变更内容
V1.0 2025-12-08 初版规划Phase 1-4功能
V1.1 2025-12-08 架构重构改为预写Python函数
V1.2 2025-12-08 Phase 1-2完成7个核心功能上线
V1.3 2025-12-10 NA处理优化4个功能支持空值处理Pivot优化保留未选列+原始列顺序计算列方案B实施安全列名映射UX优化列头tooltip+预览提示可关闭+滚动条优化
V1.4 2025-12-10 缺失值填补功能开发6种简单填补均值/中位数/众数/固定值/前向/后向)+MICE多重插补自动精度检测分类列识别功能按钮调整删除"去重"和"多重插补""删除缺失值"改为"缺失值处理"状态开发完成MICE的DataFrame shape问题待调试

文档结束