Files
AIclinicalresearch/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_功能按钮开发计划_V1.0.md
HaHafeng f729699510 feat(dc): Complete Tool C quick action buttons Phase 1-2 - 7 functions
Summary:
- Implement 7 quick action functions (filter, recode, binning, conditional, dropna, compute, pivot)
- Refactor to pre-written Python functions architecture (stable and secure)
- Add 7 Python operations modules with full type hints
- Add 7 frontend Dialog components with user-friendly UI
- Fix NaN serialization issues and auto type conversion
- Update all related documentation

Technical Details:
- Python: operations/ module (filter.py, recode.py, binning.py, conditional.py, dropna.py, compute.py, pivot.py)
- Backend: QuickActionService.ts with 7 execute methods
- Frontend: 7 Dialog components with complete validation
- Toolbar: Enable 7 quick action buttons

Status: Phase 1-2 completed, basic testing passed, ready for further testing
2025-12-08 17:38:08 +08:00

34 KiB
Raw Blame History

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

文档版本: V1.2 (Phase 2 完成版)
创建日期: 2025-12-08
最后更新: 2025-12-08
负责人: AI开发团队
项目状态: Phase 1-2 已完成7个核心功能可用


🔥 重要架构变更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 已完成
生成分类变量(分箱) P0 已完成
条件生成列 P0 已完成
生成新变量(计算列) P1 已完成
数据清理 删除缺失值 P0 已完成
去重 P1 ⏸️ 暂不开发
数据重塑 长表→宽表Pivot P1 已完成
高级功能 缺失值填补 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个核心功能上线

文档结束