You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Mann-Whitney U检验的正确配置及结果异常排查

问题描述

我有一个18335行×748列的DataFrame,想用scipy.stats执行Mann-Whitney U检验,对每一列比较leiden=0的样本与leiden≠0的样本,但不确定正确实现方式。尝试了以下代码后,发现结果DataFrame里出现了leiden列的p值,怀疑操作有误。

尝试的代码

import pandas as pd
from scipy.stats import mannwhitneyu


# Perform Mann-Whitney U test for leiden=0 and leiden=1 for each column
results = {}

for column in df.columns[1:]:  # Skip the 'leiden' column
    group0 = df[df['leiden'] == 0][column]
    group1 = df[df['leiden'] == 1][column]

    statistic, p_value = mannwhitneyu(group0, group1, alternative='two-sided')
    
    results[column] = {
        'Mann-Whitney U Statistic': statistic,
        'P-Value': p_value
    }

# Create a DataFrame from the results
results_df = pd.DataFrame.from_dict(results, orient='index')

# Save the results as a CSV file
results_df.to_csv('mannwhitneyu_results.csv')

# Display the results DataFrame
print(results_df)

原始DataFrame示例

LeidenAlx1Alx17Arid3a
52035040
05050050
72035040
0405050
83035040
07050050

当前代码输出结果

ColumnMann-Whitney U Statisticp value
Leiden0.00.000000e+00
Alx11994937.54.87711e-205
Alx1718680927.01.2641e-44
Arid3a10927.01.261841e-44

问题分析与修正

你的代码存在两个核心问题:

  • 分组逻辑错误:当前代码是比较leiden=0和leiden=1的样本,但需求是比较leiden=0和所有leiden≠0的样本,分组范围不符合要求。
  • 列选择逻辑不可靠:用df.columns[1:]跳过第一列,依赖leiden列是第一列的假设,一旦列顺序变动就会错误遍历到leiden列,这也是结果里出现Leiden行的原因。

修正后的代码

import pandas as pd
from scipy.stats import mannwhitneyu

results = {}
# 显式排除leiden列,指定要检验的目标列
test_columns = [col for col in df.columns if col != 'leiden']

for column in test_columns:
    # 按需求正确分组:leiden=0 对比 leiden≠0
    group0 = df.loc[df['leiden'] == 0, column]
    group_non0 = df.loc[df['leiden'] != 0, column]
    
    # 处理空组情况,避免检验报错
    if len(group0) == 0 or len(group_non0) == 0:
        results[column] = {
            'Mann-Whitney U Statistic': None,
            'P-Value': None
        }
        continue
    
    statistic, p_value = mannwhitneyu(group0, group_non0, alternative='two-sided')
    
    results[column] = {
        'Mann-Whitney U Statistic': statistic,
        'P-Value': p_value
    }

# 生成结果DataFrame并格式化索引
results_df = pd.DataFrame.from_dict(results, orient='index').reset_index().rename(columns={'index': 'Column'})

results_df.to_csv('mannwhitneyu_results.csv', index=False)
print(results_df)

关键说明

  • 精准列筛选:通过列表推导式显式排除leiden列,彻底避免结果中出现Leiden行的问题。
  • 符合需求的分组:用df['leiden'] != 0筛选所有非0组样本,匹配你最初的检验需求。
  • 健壮性处理:增加空组判断,避免因某一组无样本导致检验报错,让代码更稳定。

内容的提问来源于stack exchange,提问作者pythonbeginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:25:58