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
This commit is contained in:
2025-12-08 17:38:08 +08:00
parent af325348b8
commit f729699510
158 changed files with 13814 additions and 273 deletions

View File

@@ -527,3 +527,5 @@ df['creatinine'] = pd.to_numeric(df['creatinine'], errors='coerce')
**文档状态**: ✅ 已确认
**下一步**: 开始Day 3开发AICodeService实现

View File

@@ -942,3 +942,5 @@ export const aiController = new AIController();
**准备开始开发!** 🚀

View File

@@ -1276,3 +1276,5 @@ npm install react-markdown
🚀 **准备好开始Day 4开发了吗**

View File

@@ -1,11 +1,11 @@
# 工具C MVP开发 - To-do List
> **文档版本**v1.2
> **文档版本**v1.3
> **创建日期**2025-12-06
> **最后更新**2025-12-07
> **最后更新**2025-12-08
> **预计工期**3周15个工作日
> **实际进度**Day 1-5完成Week 1 完成
> **参考文档**[工具C_MVP开发计划_V1.0.md](./工具C_MVP开发计划_V1.0.md)
> **实际进度**Week 1-2完成功能按钮Phase 1-2完成✅
> **参考文档**[工具C_MVP开发计划_V1.0.md](./工具C_MVP开发计划_V1.0.md), [工具C_功能按钮开发计划_V1.0.md](./工具C_功能按钮开发计划_V1.0.md)
---
@@ -18,7 +18,32 @@
| **Week 3: 测试优化** | 8 | 0 | 0 | 8 | 0% |
| **总计** | **30** | **12** | **0** | **18** | **40%** |
**最新更新**2025-12-07 23:00 **Day 5 完成** + Ant Design X 集成
**最新更新**2025-12-08 16:00 **功能按钮Phase 1-2完成** + 7个功能上线
---
## 🎉 最新进展2025-12-08
### ✅ 功能按钮开发Phase 1-2
**7个核心功能已完成**
1. ✅ 高级筛选器多条件AND/OR
2. ✅ 数值映射(重编码)
3. ✅ 生成分类变量(等宽/等频/自定义切点)
4. ✅ 条件生成列IF-THEN-ELSE复杂逻辑
5. ✅ 删除缺失值(按行/列,阈值控制)
6. ✅ 计算列公式构建器10+数学函数)
7. ✅ Pivot转换长表→宽表
**技术架构**
- ✅ 预写Python函数架构稳定、安全、高性能
- ✅ 7个Python operations模块
- ✅ 7个API端点`/api/operations/*`
- ✅ 完整的前后端集成
- ✅ 友好的UI交互Dialog + 实时验证)
**待开发**
- ⏳ 多重插补MICE- 最后一个功能
---

View File

@@ -0,0 +1,959 @@
# 工具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`(完整错误处理)
- ✅ 前端UI7个Dialog组件完整交互界面
- ✅ 前端工具栏7个功能按钮已启用
- ✅ 删除:`QuickActionCodeGenerator.ts`(不再使用)
**架构对比**
| 维度 | 旧方案 | ✅ 新方案 |
|------|--------|---------|
| 稳定性 | ⚠️ 字符串拼接易出错 | ✅ 预写函数经过测试 |
| 安全性 | ⚠️ 有注入风险 | ✅ 无代码注入风险 |
| 性能 | ⚠️ 需解析代码 | ✅ 直接调用函数 |
| 可维护 | ⚠️ 后端拼接字符串 | ✅ Python集中管理 |
| 可测试 | ❌ 难以测试 | ✅ 易于单元测试 |
---
## 📋 文档目录
- [1. 概述](#1-概述)
- [2. 设计原则](#2-设计原则)
- [3. 功能清单](#3-功能清单)
- [4. 分期开发计划](#4-分期开发计划)
- [5. 技术架构](#5-技术架构)
- [6. 详细设计](#6-详细设计)
- [7. 验收标准](#7-验收标准)
---
## 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前端调用
```typescript
// 执行快速操作
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` 配置。
```python
# 高级筛选示例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后端服务
```typescript
// 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预写函数
```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` 中配置:
```bash
# Python微服务地址必需
EXTRACTION_SERVICE_URL=http://localhost:8000
# 生产环境示例
# EXTRACTION_SERVICE_URL=http://python-service:8000
# EXTRACTION_SERVICE_URL=https://api.yourdomain.com/python
```
#### 代码实现
```typescript
// 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行
│ │
│ [取消] [预览] [应用] │
└─────────────────────────────────────────┘
```
#### 条件运算符
- 数值列:`=`, `≠`, `>`, `<`, `≥`, `≤`
- 文本列:`等于`, `不等于`, `包含`, `不包含`, `以...开头`, `以...结尾`
- 通用:`为空`, `不为空`
#### 生成代码示例
```python
# 单条件
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______] │ │
│ └─────────────────┴─────────────┘ │
│ │
│ ☑️ 创建新列(推荐) │
│ 新列名:[研究中心_编码_______] │
│ │
│ [取消] [预览] [执行] │
└─────────────────────────────────────┘
```
#### 生成代码示例
```python
# 创建新列
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] │
│ │
│ 新列名:[住院患者暴露分组_____] │
│ │
│ [取消] [预览分布] [执行] │
└─────────────────────────────────────┘
```
#### 生成代码示例
```python
# 二分类(单切点)
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行] [执行] │
└─────────────────────────────────────────┘
```
#### 技术实现
**前端数据结构**
```typescript
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
}
```
**生成代码示例**
```python
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 │
│ [ ] ...(选择其他列) │
│ │
│ 重复值处理: │
│ ● 取第一个 ○ 取最后一个 │
│ ○ 求平均值 ○ 求和 │
│ │
│ [取消] [预览结构] [执行] │
└─────────────────────────────────────┘
```
#### 生成代码示例
```python
# 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`
```python
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个核心功能上线 |
---
**文档结束**