如何在分组数据上执行SciPy正态性检验(如normaltest)?
解决Pokemon分组Attack属性的正态性检验问题
问题根源
- 第一个报错:
normaltest底层依赖的skewtest要求样本量至少为8,你的数据中存在样本数不足8的分组(比如Flying分组仅4个样本),直接触发检验无效的错误。 - 第二个报错:
normaltest仅支持单次处理单个数据集,你通过解包传递了18个分组数据,超出函数参数范围,导致类型错误。
正确实现方案
方案1:过滤小样本后执行检验
先筛选出样本量≥8的分组,确保检验有效:
import numpy as np import pandas as pd from scipy.stats import normaltest # 读取数据集 data = pd.read_csv("pokemon.csv") # 过滤样本量≥8的分组 valid_groups = data.groupby('Type 1').filter(lambda group: len(group) >= 8) # 定义检验函数,返回统计量和p值 def normality_test(series): stat, p_val = normaltest(series) return pd.Series({'检验统计量': stat, 'p值': p_val}) # 对每个有效分组的Attack属性执行检验 test_results = valid_groups.groupby('Type 1')['Attack'].apply(normality_test).unstack() # 输出结果 print(test_results)
方案2:保留所有分组,标记小样本
如果需要保留所有分组,对小样本做标记而非直接过滤:
import numpy as np import pandas as pd from scipy.stats import normaltest data = pd.read_csv("pokemon.csv") def normality_test_with_note(series): if len(series) < 8: return pd.Series({ '检验统计量': np.nan, 'p值': np.nan, '状态': '样本量不足8,无法完成检验' }) stat, p_val = normaltest(series) return pd.Series({ '检验统计量': stat, 'p值': p_val, '状态': '检验有效' }) # 生成全部分组的检验结果 full_results = data.groupby('Type 1')['Attack'].apply(normality_test_with_note).unstack() print(full_results)
结果解读
- 当p值 > 0.05(常用显著性水平)时,无法拒绝“数据符合正态分布”的原假设,可认为该分组Attack属性服从正态分布;
- 当p值 ≤ 0.05时,拒绝原假设,认为数据不符合正态分布。
内容的提问来源于stack exchange,提问作者Nguyen Phan
相关产品推荐
相关产品推荐

