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

用Pandas处理DataFrame列计算卡方值结果不符,如何解决?

问题根源与修正方案

核心错误分析

你的代码存在两个关键问题,直接导致卡方检验结果完全偏离预期:

  1. 错误使用pd.crosstab:你的数据集里Observed是每个分组的观测频数,Expected是对应分组的期望频数,并非两个独立的分类变量。用pd.crosstab会生成观测值与期望值的交叉计数表,这完全不是卡方检验需要的输入结构,最终得到的列联表毫无统计意义。
  2. 混淆卡方检验类型:你要做的是拟合优度卡方检验(验证观测频数是否符合给定的期望分布),但误用了用于独立性检验的chi2_contingency函数。后者要求输入的是两个分类变量的交叉频数表,而不是单组观测与期望的对应数组。

修正步骤

1. 正确提取DataFrame列

直接从DataFrame中提取观测和期望的数值数组即可,不需要生成交叉表:

obs = df['Observed'].values
exp = df['Expected'].values

2. 使用拟合优度卡方检验

调用scipy.stats.chisquare函数(专门用于拟合优度检验),传入观测数组和期望数组:

from scipy.stats import chisquare

c, p = chisquare(obs, f_exp=exp)

3. 验证结果

拟合优度检验的自由度为类别数-1,这里有11个分组,自由度为10。计算后得到的p值会接近预期的0.411,卡方统计量也会符合理论计算值。

修正后的完整代码

import pandas as pd
from scipy.stats import chisquare
import logging 

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

# 读取数据集
df = pd.read_csv('dice_rolls.csv') 
logging.debug(f"观测频数:\n{df['Observed']}")
logging.debug(f"期望频数:\n{df['Expected']}")

# 提取观测和期望数组
obs = df['Observed'].values
exp = df['Expected'].values

# 执行拟合优度卡方检验
c, p = chisquare(obs, f_exp=exp)
dof = len(obs) - 1  # 计算自由度

# 输出结果
logging.debug(f'卡方统计量: {c}')
logging.debug(f'p值: {p}')
logging.debug(f'自由度: {dof}')

预期输出说明

运行修正后的代码,会得到:

  • 卡方统计量约为10.656
  • p值约为0.411
  • 自由度为10
    完全符合你的预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:50:26