使用Scipy.mannwhitneyu时如何处理含NaN的临床药物响应数据
解决Mann-Whitney U检验中NaN值的处理方案
核心处理逻辑
- 同步过滤无响应标签的样本:先移除B数据集(
test_dr_new)中响应为NaN的行,同时对应移除A数据集(logIC50_df)的同索引行,只保留有明确"敏感/耐药"标签的样本。 - 过滤单药物组内的NaN值:对每个药物,分别从耐药组和敏感组中移除logIC50为NaN的样本,避免无效值干扰检验计算。
- 跳过样本量不足的药物:若某药物的耐药组或敏感组过滤后样本量小于2,Mann-Whitney U检验无法得到有效结果,直接跳过该药物。
修改后的代码
from scipy.stats import mannwhitneyu import pandas as pd p_values = {} # 存储每个药物的p值 significance_level = 0.05 # 第一步:同步过滤无响应标签的样本 valid_indices = test_dr_new.iloc[:,0].dropna().index filtered_log_ic50 = logIC50_df.loc[valid_indices] filtered_response = test_dr_new.loc[valid_indices].iloc[:,0] # 遍历每个药物 for drug in filtered_log_ic50.columns: # 整合当前药物的logIC50与响应标签 drug_data = pd.DataFrame({ 'log_ic50': filtered_log_ic50[drug], 'response': filtered_response }) # 第二步:过滤组内的NaN值 resistant_data = drug_data[drug_data['response'] == "Resistant"]['log_ic50'].dropna() sensitive_data = drug_data[drug_data['response'] == "Sensitive"]['log_ic50'].dropna() # 第三步:检查样本量是否满足检验要求 if len(resistant_data) < 2 or len(sensitive_data) < 2: print(f"跳过药物 {drug}:耐药组/敏感组样本量不足") p_values[drug] = None continue # 执行单侧Mann-Whitney U检验 statistic, p_value = mannwhitneyu(resistant_data, sensitive_data, alternative='greater') p_values[drug] = p_value print(f"药物 {drug} 的p值:{p_value}") # 统计具有显著差异的药物数量(排除无效项) num_significant = sum(p < significance_level for p in p_values.values() if p is not None) print(f"\n具有统计学显著差异的药物数量:{num_significant}") # 结果解读 if num_significant > 0: print("拒绝原假设:耐药肿瘤的log(IC50)估计值显著高于敏感肿瘤") else: print("无法拒绝原假设:耐药与敏感肿瘤的log(IC50)估计值无显著差异")
关键修改说明
- 通过
dropna()同步过滤标签缺失的样本,确保后续分组的样本均有明确的响应类型。 - 对单药物的分组数据再次执行
dropna(),剔除该药物logIC50缺失的无效样本。 - 增加样本量校验,避免因样本过少产生无意义的检验结果。
- 用
None标记无效药物的p值,统计显著数量时自动排除这类项。
内容的提问来源于stack exchange,提问作者Shazzz
相关产品推荐
相关产品推荐

