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
34 KiB
34 KiB
工具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.ts(7个执行方法) - ✅ Node.js后端:
QuickActionController.ts(完整错误处理) - ✅ 前端UI:7个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 用户体验原则
- 80/20法则:用按钮解决80%的简单需求,用AI对话解决20%的复杂需求
- 渐进式披露:简单功能默认显示,复杂选项折叠/高级模式
- 即时反馈:提供预览功能,让用户在执行前看到结果
- 可撤销性:支持撤销(未来版本)或提供"创建副本"选项
2.2 技术原则
- ✅ 预写函数架构:功能按钮调用预写的、经过测试的Python函数(而非动态生成代码)
- 无状态设计:每个操作独立,不依赖前序状态
- 安全可靠:预写函数经过充分测试和验证,无代码注入风险
- 性能优先:直接调用函数,避免代码解析开销,优化大数据集处理
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个月后)
- 操作推荐:根据数据特征推荐合适的操作
- 自动诊断:检测数据质量问题(缺失、异常、重复)
- 批量操作:一次性应用多个操作
- 操作模板:保存常用操作序列
Phase 6:协作增强(3-6个月后)
- 操作历史:查看、回退、分享操作历史
- 团队模板:团队共享清洗模板
- 数据版本:支持数据快照和版本管理
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个核心功能上线 |
文档结束