# 工具C - 缺失值处理功能开发计划 ## 📋 概述 **目标**:将现有的"删除缺失值"功能升级为综合的"缺失值处理"功能,包括删除、填补、高级填补三种策略。 **设计方案**:方案B - 合并对话框 + Tab切换 **核心原则**: - ✅ **填补操作创建新列**(保留原始数据,便于对比) - ✅ **新列紧邻原列**(方便用户查看和比较) - ✅ **MICE功能必须实现**(医学研究核心需求) - ✅ **无需撤销功能**(原始数据未被修改) --- ## 🎯 功能需求 ### Phase 1:必备功能(本次开发) #### Tab 1:删除缺失值 ✅ 已有 - 保留现有功能 - 删除包含缺失值的行 - 删除缺失率过高的列 #### Tab 2:填补缺失值 ⭐ 新增 1. **均值填补**(Mean Imputation) - 适用于:数值型变量,正态分布 - 实现:创建新列,填充均值 2. **中位数填补**(Median Imputation) - 适用于:数值型变量,偏态分布 - 实现:创建新列,填充中位数 3. **众数填补**(Mode Imputation) - 适用于:分类变量、离散型数值 - 实现:创建新列,填充众数 4. **固定值填补**(Constant Imputation) - 适用于:任何类型,用户指定值 - 实现:创建新列,填充指定值 5. **前向填充**(Forward Fill) - 适用于:时间序列数据、有顺序的观察数据 - 实现:`df[column].fillna(method='ffill')`,用前一个非缺失值填充 - 示例:[10, NaN, NaN, 20] → [10, 10, 10, 20] 6. **后向填充**(Backward Fill) - 适用于:时间序列数据、有顺序的观察数据 - 实现:`df[column].fillna(method='bfill')`,用后一个非缺失值填充 - 示例:[10, NaN, NaN, 20] → [10, 20, 20, 20] **注意**:所有填补方法都会创建新列(如`体重_填补`),新列紧邻原列,便于对比验证。 #### Tab 3:高级填补 ⭐ 新增 1. **MICE多重插补**(Multivariate Imputation by Chained Equations) - 适用于:缺失率5%-30%,需要考虑变量间关系 - 实现:使用 `sklearn.impute.IterativeImputer` ### Phase 2:未来扩展(本次不开发) - 分组填补(Grouped Imputation) - 线性插值(Linear Interpolation) - KNN填补(KNN Imputation) - 组合填补(根据条件使用不同填补方法) --- ## 🎨 UI设计 ### 1. 按钮重命名 **原**:`[删除缺失值]` **新**:`[缺失值处理]` ### 2. 对话框结构 ``` ┌───────────────────────────────────────────────────────┐ │ 缺失值处理 [X] │ ├───────────────────────────────────────────────────────┤ │ ┌────────┬────────┬──────────┐ │ │ │ 删除 │ 填补 │ 高级填补 │ ← Ant Design Tabs │ │ └────────┴────────┴──────────┘ │ ├───────────────────────────────────────────────────────┤ │ │ │ 【Tab内容区域】 │ │ │ │ │ │ [取消] [执行处理] │ └───────────────────────────────────────────────────────┘ ``` ### 3. Tab 2(填补)详细设计 ``` ┌───────────────────────────────────────────────────────┐ │ 【Tab 2: 填补缺失值】 │ │ │ │ 原始列:[体重(kg)▼] │ │ ⚠️ 仅支持单列填补 │ │ │ │ 新列名:[体重_填补 ] ← 用户可修改 │ │ 💡 新列将创建在原列旁边,便于对比 │ │ │ │ 📊 缺失值统计: │ │ ┌──────────────────────────────────────────────┐ │ │ │ • 当前缺失:125个(15.6%) │ │ │ │ • 有效值:675个(84.4%) │ │ │ │ • 数据类型:数值型 │ │ │ │ • 有效值范围:45.2 - 98.5 kg │ │ │ │ • 有效值均值:70.3 kg │ │ │ │ • 有效值中位数:68.5 kg │ │ │ │ • 推荐方法:中位数填补(数据偏态)⭐ │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ 填补方法: │ │ ⚪ 均值填补(适合正态分布的数值变量) │ │ ⚪ 中位数填补(适合偏态分布的数值变量)⭐ │ │ ⚪ 众数填补(适合分类变量或离散数值) │ │ ⚪ 固定值填补:[_______] ← 用户输入 │ │ ⚪ 前向填充(用前一个值填充,适合时间序列) │ │ ⚪ 后向填充(用后一个值填充,适合时间序列) │ │ │ │ 📈 填补预览: │ │ ┌──────────────────────────────────────────────┐ │ │ │ • 填补值:68.5 kg │ │ │ │ • 填补后均值:70.2 kg(原75.3 kg) │ │ │ │ • 填补后标准差:12.5 kg(原10.8 kg) │ │ │ │ • 将创建新列:"体重_填补" │ │ │ │ • 原列"体重(kg)"保持不变 ✅ │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ ✅ 优势:原始数据保留,可随时对比验证 │ │ │ │ [取消] [执行填补] │ └───────────────────────────────────────────────────────┘ ``` ### 4. Tab 3(高级填补)详细设计 ``` ┌───────────────────────────────────────────────────────┐ │ 【Tab 3: 高级填补 - MICE多重插补】⭐ 必须实现 │ │ │ │ ⭐ MICE多重插补 │ │ (Multivariate Imputation by Chained Equations) │ │ │ │ 选择要填补的列(可多选): │ │ ┌──────────────────────────────────────────────┐ │ │ │ ☑ 体重(kg) 缺失:125(15.6%) │ │ │ │ ☑ 收缩压(mmHg) 缺失:82(10.3%) │ │ │ │ ☐ BMI 缺失:3(0.4%) │ │ │ │ ☐ 舒张压(mmHg) 缺失:0(0%) │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ 新列命名规则: │ │ ☑ 自动命名:原列名 + "_MICE" │ │ 示例:体重(kg) → 体重(kg)_MICE │ │ 收缩压(mmHg) → 收缩压(mmHg)_MICE │ │ │ │ 参数设置: │ │ 迭代次数:[10▼] (默认10次,范围5-50) │ │ 随机种子:[42 ] (确保结果可重复) │ │ │ │ 📊 MICE说明: │ │ ┌──────────────────────────────────────────────┐ │ │ │ MICE会根据其他变量的值来预测缺失值。 │ │ │ │ │ │ │ │ ✅ 适用场景: │ │ │ │ • 缺失率5%-30% │ │ │ │ • 需要考虑变量间的相关性 │ │ │ │ • 多个变量同时有缺失 │ │ │ │ • 医学研究高质量填补的首选方法 ⭐ │ │ │ │ │ │ │ │ ⚠️ 注意: │ │ │ │ • 计算时间较长(10万行约1分钟) │ │ │ │ • 需要足够的有效样本(建议>50%有效) │ │ │ │ • 新列将创建在各原列旁边,便于对比 │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ 💡 新列位置:每个新列紧邻其原列,便于逐列验证 │ │ │ │ [取消] [执行MICE填补] │ └───────────────────────────────────────────────────────┘ ``` --- ## 🛠️ 技术实现方案 ### 1. Python端(extraction_service) #### 新增文件:`operations/fillna.py` ```python """ 缺失值填补 - 预写函数 支持均值、中位数、众数、固定值、MICE填补 """ import pandas as pd import numpy as np from typing import Literal, Optional, List, Union, Any from sklearn.impute import IterativeImputer def fillna_simple( df: pd.DataFrame, column: str, new_column_name: str, method: Literal['mean', 'median', 'mode', 'constant', 'ffill', 'bfill'], fill_value: Any = None ) -> dict: """ 简单填补缺失值(创建新列) Args: df: 输入数据框 column: 原始列名 new_column_name: 新列名(如"体重_填补") method: 填补方法 - 'mean': 均值填补 - 'median': 中位数填补 - 'mode': 众数填补 - 'constant': 固定值填补 - 'ffill': 前向填充(用前一个非缺失值) - 'bfill': 后向填充(用后一个非缺失值) fill_value: 固定值(method='constant'时必填) Returns: { 'df': 包含新列的数据框(新列紧邻原列), 'stats': { 'original_column': 原列名, 'new_column': 新列名, 'missing_before': 缺失数量, 'fill_value': 填补的值, 'mean_after': 填补后均值, 'std_after': 填补后标准差 } } 实现细节: 1. 复制原列数据 2. 执行填补 3. 使用 df.insert() 将新列插入到原列旁边 4. 返回包含新列的完整数据框 """ def get_column_missing_stats( df: pd.DataFrame, column: str ) -> dict: """ 获取列的缺失值统计信息 Returns: { 'missing_count': 缺失数量, 'missing_rate': 缺失率, 'valid_count': 有效值数量, 'data_type': 数据类型, 'value_range': [min, max], # 仅数值型 'mean': 均值, # 仅数值型 'median': 中位数, # 仅数值型 'mode': 众数, 'recommended_method': 推荐的填补方法 } """ def fillna_mice( df: pd.DataFrame, columns: List[str], n_iterations: int = 10, random_state: int = 42 ) -> dict: """ MICE多重插补(创建新列)⭐ 必须实现 Args: df: 输入数据框 columns: 要填补的列名列表(如["体重(kg)", "收缩压(mmHg)"]) n_iterations: 迭代次数(默认10,范围5-50) random_state: 随机种子(默认42,确保结果可重复) Returns: { 'df': 包含所有新列的数据框(每个新列紧邻其原列), 'stats': { column: { 'original_column': 原列名, 'new_column': 新列名(原名_MICE), 'missing_before': 缺失数量, 'filled_count': 填补数量, 'mean_before': 填补前均值, 'mean_after': 填补后均值 } } } 实现细节: 1. 对所选列执行MICE填补 2. 为每列创建新列(命名:原列名_MICE) 3. 使用 df.insert() 将每个新列插入到其原列旁边 4. 返回包含所有新列的完整数据框 示例: 原列:体重(kg)、收缩压(mmHg) 新列:体重(kg)_MICE、收缩压(mmHg)_MICE 结果顺序:体重(kg)、体重(kg)_MICE、收缩压(mmHg)、收缩压(mmHg)_MICE、... """ ``` #### 修改文件:`main.py` ```python # 新增API端点 @app.post("/fillna-simple") async def operation_fillna_simple(request: FillnaSimpleRequest): """简单填补缺失值""" @app.post("/fillna-stats") async def get_fillna_stats(request: FillnaStatsRequest): """获取列的缺失值统计""" @app.post("/fillna-mice") async def operation_fillna_mice(request: FillnaMiceRequest): """MICE多重插补""" ``` ### 2. Node.js后端(backend) #### 修改文件:`services/QuickActionService.ts` ```typescript // 新增方法 async executeFillnaSimple(params: { sessionId: string; column: string; method: 'mean' | 'median' | 'mode' | 'constant' | 'ffill' | 'bfill'; fillValue?: any; }): Promise async getFillnaStats(params: { sessionId: string; column: string; }): Promise async executeFillnaMice(params: { sessionId: string; columns: string[]; nIterations: number; }): Promise ``` #### 修改文件:`controllers/QuickActionController.ts` ```typescript // 新增处理方法 async handleFillnaSimple(request, reply) async getFillnaStats(request, reply) async handleFillnaMice(request, reply) ``` ### 3. 前端(frontend-v2) #### 重命名文件 - `DropnaDialog.tsx` → `MissingValueDialog.tsx` #### 修改文件:`MissingValueDialog.tsx` ```typescript interface MissingValueDialogProps { open: boolean; onClose: () => void; sessionId: string; columns: Array<{ id: string; name: string; type?: string }>; onSuccess: () => void; } // 新增状态 const [activeTab, setActiveTab] = useState<'delete' | 'fill' | 'mice'>('fill'); const [selectedColumn, setSelectedColumn] = useState(''); const [fillMethod, setFillMethod] = useState<'mean' | 'median' | 'mode' | 'constant' | 'ffill' | 'bfill'>('median'); const [fillValue, setFillValue] = useState(null); const [columnStats, setColumnStats] = useState(null); // Tab 1: 删除(保留原有逻辑) // Tab 2: 填补(新增) // Tab 3: MICE(新增) ``` #### 修改文件:`index.tsx` ```typescript // 更新按钮组 const actionButtons = [ // ... { key: 'missing', icon: , label: '缺失值处理', // ← 重命名 onClick: () => setMissingValueDialogOpen(true), }, // ... ]; ``` --- ## 📂 文件修改清单 ### 新增文件 1. `extraction_service/operations/fillna.py` - 填补功能实现 2. `docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_缺失值处理功能开发计划.md` - 本文档 ### 修改文件 #### Python端 1. `extraction_service/main.py` - 新增 `/fillna-simple` 端点 - 新增 `/fillna-stats` 端点 - 新增 `/fillna-mice` 端点 #### Node.js后端 2. `backend/src/modules/dc/tool-c/services/QuickActionService.ts` - 新增 `executeFillnaSimple` 方法 - 新增 `getFillnaStats` 方法 - 新增 `executeFillnaMice` 方法 3. `backend/src/modules/dc/tool-c/controllers/QuickActionController.ts` - 新增 `handleFillnaSimple` 处理方法 - 新增 `getFillnaStats` 处理方法 - 新增 `handleFillnaMice` 处理方法 #### 前端 4. `frontend-v2/src/modules/dc/pages/tool-c/components/DropnaDialog.tsx` - **重命名为** `MissingValueDialog.tsx` - 新增 Tabs 组件(删除/填补/高级填补) - Tab 1: 保留原有删除功能 - Tab 2: 新增简单填补功能(均值/中位数/众数/固定值) - Tab 3: 新增MICE填补功能 5. `frontend-v2/src/modules/dc/pages/tool-c/index.tsx` - 更新按钮标签:`删除缺失值` → `缺失值处理` - 更新 Dialog 组件引用 6. `frontend-v2/src/modules/dc/api/index.ts` - 新增 `fillnaSimple` API - 新增 `getFillnaStats` API - 新增 `fillnaMice` API --- ## 🔄 开发步骤 ### Step 1: Python端基础功能(30min) 1. 创建 `fillna.py` 2. 实现 `fillna_simple` 函数 3. 实现 `get_column_missing_stats` 函数 4. 在 `main.py` 添加对应端点 5. 测试:使用Postman或curl测试API ### Step 2: Python端高级功能(30min) 1. 实现 `fillna_mice` 函数 2. 在 `main.py` 添加对应端点 3. 测试:使用Postman测试MICE功能 ### Step 3: Node.js后端(20min) 1. 修改 `QuickActionService.ts` 2. 修改 `QuickActionController.ts` 3. 测试:确保API转发正常 ### Step 4: 前端UI重构(40min) 1. 重命名 `DropnaDialog.tsx` → `MissingValueDialog.tsx` 2. 实现Tabs结构 3. Tab 1: 迁移原有删除功能 4. Tab 2: 实现简单填补UI 5. Tab 3: 实现MICE填补UI 6. 更新 `index.tsx` 中的引用和按钮标签 ### Step 5: 前端API集成(20min) 1. 在 `api/index.ts` 添加新API 2. 集成到 `MissingValueDialog.tsx` 3. 实现实时统计获取 4. 实现填补预览 ### Step 6: 端到端测试(30min) 1. 测试均值填补 2. 测试中位数填补 3. 测试众数填补 4. 测试固定值填补 5. 测试MICE填补 6. 测试删除功能(确保未破坏原有功能) ### Step 7: 优化和文档(20min) 1. 添加错误处理 2. 优化加载状态 3. 更新用户提示 4. 记录开发总结 **总计:约3小时** --- ## 🧪 测试计划 ### 功能测试用例 #### 测试数据准备 ``` - 数值列(正态分布):年龄(缺失15%) - 数值列(偏态分布):体重(缺失20%) - 分类列:婚姻状况(缺失10%) - 多列缺失:收缩压(15%)+ 舒张压(12%) - 时间序列列:随访血压(有顺序,缺失18%)- 用于测试前/后向填充 ``` #### 测试用例 | 编号 | 功能 | 测试场景 | 预期结果 | |------|------|----------|----------| | TC-1 | 均值填补 | 对"年龄"列使用均值填补,新列名"年龄_填补" | 创建新列,缺失值被均值填充,原列不变 ✅ | | TC-2 | 中位数填补 | 对"体重"列使用中位数填补 | 创建新列,缺失值被中位数填充 ✅ | | TC-3 | 众数填补 | 对"婚姻状况"列使用众数填补 | 创建新列,缺失值被众数填充 ✅ | | TC-4 | 固定值填补(数值) | 对"年龄"列填充固定值"0" | 创建新列,所有缺失值变为0 ✅ | | TC-5 | 固定值填补(文本) | 对"婚姻状况"列填充"未知" | 创建新列,所有缺失值变为"未知" ✅ | | TC-6 | MICE填补 | 选择"收缩压"+"舒张压",执行MICE | 创建2个新列(_MICE后缀),缺失值被预测 ✅ | | TC-7 | 新列位置验证 ⭐ | 对"列A"填补,查看新列位置 | 新列"列A_填补"紧邻原列"列A"右侧 ✅ | | TC-8 | MICE新列位置 ⭐ | 对"列A"+"列C"执行MICE | 列A_MICE在列A旁,列C_MICE在列C旁 ✅ | | TC-9 | 统计信息准确性 | 选择任意列,查看统计信息 | 显示正确的缺失数、均值、中位数等 | | TC-10 | 删除功能保留 | Tab 1删除缺失行 | 功能正常,与原功能一致 | | TC-11 | 空列处理 | 对完全无缺失的列执行填补 | 提示"该列无缺失值"或复制原列 | | TC-12 | 全缺失列处理 | 对全部缺失的列执行填补 | 提示警告,仍创建新列(全部为填补值) | | TC-13 | 重复新列名处理 | 新列名已存在 | 自动添加后缀(如"体重_填补_1")或提示 | | TC-14 | 原始数据保留 ⭐ | 填补后,检查原列 | 原列数据完全不变 ✅ | ### 边界测试 | 测试项 | 场景 | 预期 | |--------|------|------| | 超大数据集 | 10万行数据执行MICE | 显示进度,不崩溃 | | 特殊字符列名 | 列名带括号、等号 | 正常处理(使用columnMapping) | | 数据类型混合 | 对文本列执行均值填补 | 提示错误或自动跳过 | | 并发处理 | 同时打开多个Dialog | 状态隔离,不互相影响 | --- ## 📊 性能要求 | 操作 | 数据量 | 目标响应时间 | |------|--------|--------------| | 简单填补(均值/中位数/众数) | 1万行 | < 1秒 | | 简单填补 | 10万行 | < 5秒 | | MICE填补 | 1万行 | < 10秒 | | MICE填补 | 10万行 | < 60秒 | | 统计信息获取 | 任意 | < 0.5秒 | --- ## 🚨 风险和注意事项 ### 1. 数据安全 ✅ 已解决 - ✅ 填补操作创建新列,原始数据完全保留 - ✅ 新列紧邻原列,便于对比验证 - ✅ 无需撤销功能(原始数据未被修改) - ✅ 用户可随时删除填补后的列,或重新填补 ### 2. MICE性能 ⭐ 重点关注 - ⚠️ MICE在大数据集上可能很慢(10万行约1分钟) - ✅ **必须显示进度条或加载动画** - ✅ 添加"预计耗时"提示(基于数据量估算) - ✅ 提供"取消执行"按钮(长时间任务) - 💡 优化建议:考虑使用Web Worker或后台任务队列 ### 3. 数据类型兼容性 - ⚠️ 均值/中位数只适用于数值列 - ✅ 需要前端验证列的数据类型 - ✅ 后端也需要校验并返回友好错误 ### 4. 列名特殊字符 - ⚠️ 列名可能包含特殊字符 - ✅ 使用现有的 `columnMapping` 机制 - ✅ 确保与compute列功能一致 ### 5. 全部缺失的列 - ⚠️ 如果列全部为空,均值/中位数为NaN - ✅ 需要特殊处理并提示用户 --- ## 📝 依赖项 ### Python依赖(需要确认) ``` pandas >= 1.5.0 numpy >= 1.23.0 scikit-learn >= 1.2.0 # ← MICE需要 ``` ### 前端依赖 - 无新增依赖(使用现有的Ant Design组件) --- ## 🎯 验收标准 ### 必须满足 ⭐ 1. ✅ **MICE功能完全实现**(非常重要!) 2. ✅ **新列位置正确**(紧邻原列右侧) 3. ✅ **原始数据完全保留**(填补不修改原列) 4. ✅ 所有测试用例通过(特别是TC-7, TC-8, TC-14) 5. ✅ 无Breaking Changes(原有删除功能不受影响) 6. ✅ UI符合设计稿(3个Tab切换流畅) 7. ✅ 代码通过Linter检查 8. ✅ 添加适当的日志和错误处理 9. ✅ MICE显示进度条或加载动画 ### 加分项 1. ⭐ 性能优于预期 2. ⭐ UI动画流畅 3. ⭐ 错误提示友好且具体 4. ⭐ 添加单元测试 --- ## 📅 时间估算(已更新) | 阶段 | 预计时间 | 备注 | |------|----------|------| | Python后端 - 简单填补 | 40分钟 | fillna.py基础功能 | | Python后端 - MICE填补 ⭐ | 50分钟 | **必须实现**,包括sklearn集成 | | Python后端 - 新列插入逻辑 | 30分钟 | df.insert()实现,确保新列紧邻原列 | | Python - main.py端点 | 20分钟 | 新增3个API端点 | | Node.js后端 | 20分钟 | 简单转发 | | 前端UI - Tab结构 | 30分钟 | 3个Tab切换 | | 前端UI - Tab 2(简单填补) | 40分钟 | 表单 + 统计 + 新列名输入 | | 前端UI - Tab 3(MICE) ⭐ | 40分钟 | 多选列 + 参数 + 进度条 | | API集成 | 30分钟 | 前端调用后端,处理新列名 | | 测试 | 40分钟 | 14个测试用例,重点测试新列位置 | | 优化和文档 | 20分钟 | 错误处理 + 文档 | | **总计** | **约5-6小时** | **包含完整MICE实现** ⭐ | **说明**: - MICE是医学研究的核心需求,必须完整实现 - 新列插入逻辑需要仔细处理,确保位置正确 - 前端需要额外时间处理新列名输入和预览 --- ## 📚 参考资料 ### 缺失值填补理论 - [sklearn.impute.IterativeImputer文档](https://scikit-learn.org/stable/modules/generated/sklearn.impute.IterativeImputer.html) - [MICE算法原理](https://www.jstatsoft.org/article/view/v045i03) ### 医学研究中的缺失值处理 - 均值/中位数填补:最常用,简单快速 - MICE:高质量研究首选,考虑变量间关系 - 分组填补:不同人群特征差异大时使用 --- ## ✅ 开发前确认清单 已确认事项 ✅: - [x] **MICE功能必须开发**(医学研究核心需求)✅ - [x] **填补方式:创建新列**(保留原始数据)✅ - [x] **新列位置:紧邻原列**(便于对比验证)✅ - [x] **无需撤销功能**(原始数据未被修改)✅ - [x] UI设计符合预期(3个Tab切换)✅ - [x] 功能范围合理(Phase 1不包括分组填补、插值等)✅ - [x] 性能要求合理(MICE 10万行<60秒)✅ - [x] 测试用例完整(14个测试用例)✅ - [x] 时间估算可接受(约3-4小时)✅ ## 🚀 准备开始开发 所有确认清单已完成,随时可以开始实施! --- ## 📝 更新记录 ### 2025-12-10 更新(用户要求) **新增功能**: 1. ✅ **前向/后向填充加入本次开发**(原计划在Phase 2) - 前向填充(Forward Fill):用前一个非缺失值填充 - 后向填充(Backward Fill):用后一个非缺失值填充 - 适用场景:时间序列数据、有顺序的观察数据 **影响**: - Tab 2新增2个填补选项(共6种方法) - Python函数 `fillna_simple` 方法参数新增 `'ffill'` 和 `'bfill'` - 测试用例从14个增加到18个 - 开发时间从5-6小时增加到6-7小时 **适用场景说明**: - 均值/中位数:适合独立观察的数值变量 - 众数:适合分类变量 - 固定值:用户自定义场景 - **前向填充**:随访数据(如多次测量,用上次值填充) - **后向填充**:预测性数据(用未来已知值填充) - MICE:需要考虑变量间关系的高质量填补 --- ### 2025-12-09 更新(根据用户确认) **核心变更**: 1. ✅ **MICE功能必须实现**(医学研究核心需求) 2. ✅ **填补方式改为创建新列**(保留原始数据) 3. ✅ **新列位置:紧邻原列右侧**(便于对比验证) 4. ✅ **取消撤销功能**(原始数据未被修改,无需撤销) **影响**: - Python函数签名新增 `new_column_name` 参数 - UI新增"新列名"输入框 - 实现逻辑使用 `df.insert()` 确保位置正确 - 测试用例新增新列位置验证(TC-7, TC-8) - 开发时间从3小时增加到5-6小时(MICE+新列逻辑) **优势**: - ✅ 原始数据完全保留,数据安全性更高 - ✅ 新旧数据并列显示,便于验证填补效果 - ✅ 用户可多次尝试不同填补方法对比 - ✅ 符合医学研究的严谨性要求 --- **已确认,准备开始开发!** 🚀