吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 964|回复: 4
收起左侧

[求助] 【python】数据分析bug求助

[复制链接]
我是人 发表于 2020-8-12 10:17
卡方检验,调查500人,文化程度与性别是否相互独立


[Python] 纯文本查看 复制代码
import numpy as np
import pandas as pd 
from scipy import stats

sample_df = pd.read_excel('4-15.xlsx',header=0, index_col=0) # 注意要把性别列作为索引
sample_df


        高中及以上        初中        小学及以下
性别                        
男        44        36        140
女        60        60        160


# 编写一个用于卡方检验的工具
class ChisquareTest():
    def __init__(self,df):
        self.data = df.copy()
        self.summed_data = None
        self.expected_data = None
        self.chi2_data = None
        self.row_sum_name = '行合计'
        self.col_sum_name = '列合计'
        self.caculate_sum_finished = False
        self.caculate_expect_finished = False
        
    def caculate_sum(self, df = None):
        sum_original_data = df is None
        if sum_original_data:
            df = self.data.copy()
            
        df[self.row_sum_name] = df.apply(lambda row:row.sum(),axis = 1 )
        df.loc[self.col_sum_name] = df.apply(lambda col: col.sum(),axis = 0 )
        
        if sum_original_data:
            self.summed_data = df
            self.caculate_sum_finished = True
            
        return df
    
    def caculate_expect(self):
        if (not self.caculate_expect_finished):
            self.caculate_sum()
        self.expected_data = self.data.copy()
        total_sum = self.summed_data.loc[self.col_sum_name , self.row_sum_name]
        for i in range(len(self.data)):
            for j in range(len(self.data.columns)):
                row_sum = self.summed_data.iloc[i][self.row_sum_name]
                col_sum = self.summed_data.loc[self.col_sum_name][j]
                self.expected_data.iloc[i,j] = row_sum * col_sum / total_sum
            self.expected_data = self.caculate_sum(self.expected_data)
            self.caculate_expect_finished = True
            return self.expected_data
        
    def caculate_chi2(self):
        if (not self.caculate_expect_finished):
            self.caculate_expect()
        self.chi2_data = self.data.copy()
        for i in range(len(self.data)):
            for j in range(len(self.data.columns)):
                obs_value = self.data.iloc[i,j]
                exp_value = self.expected_data.iloc[i,j]
                self.chi2_data.iloc[i,j] = (obs_value - exp_value) ** 2 / exp_value
        self.chi2_data = self.caculate_sum(df = self.chi2_data)
        return self.chi2_data


chi2test = ChisquareTest(sample_df)

# 求和列表
chi2test.caculate_sum()

        高中及以上        初中        小学及以下        行合计
性别                                
男        44        36        140        220
女        60        60        160        280
列合计        104        96        300        500


以上的都正常,下面的是问题

[Python] 纯文本查看 复制代码
# 期望值表
chi2test.caculate_expect()

        高中及以上        初中        小学及以下        行合计
性别                                
男        45.76        42.24        132.0        220.0
女        60.00        60.00        160.0        280.0
列合计        105.76        102.24        292.0        500.0


这个结果和书上的不一样,书上的是
1.jpg

[Python] 纯文本查看 复制代码
# 卡方统计表
chi2test.caculate_chi2()

        高中及以上        初中        小学及以下        行合计
性别                                
男        0.067692        0.921818        0.484848        1.474359
女        0.000000        0.000000        0.000000        0.000000
列合计        0.067692        0.921818        0.484848        1.474359


这个结果和书上的不一样,书上的是
2.jpg

问题应该是是,不对第二行“女”的数据进行处理,应该是函数中的问题,咋也没找到。


谢谢大家了!

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 我是人 发表于 2020-8-12 10:39
我找到原因了

函数定义中的 i 需要+1

[Python] 纯文本查看 复制代码
    def caculate_expect(self):
        if (not self.caculate_expect_finished):
            self.caculate_sum()
        self.expected_data = self.data.copy()
        total_sum = self.summed_data.loc[self.col_sum_name , self.row_sum_name]
        for i in range(len(self.data)):
            for j in range(len(self.data.columns)):
                row_sum = self.summed_data.iloc[i+1][self.row_sum_name]
                col_sum = self.summed_data.loc[self.col_sum_name][j]
                self.expected_data.iloc[i+1,j] = row_sum * col_sum / total_sum
            self.expected_data = self.caculate_sum(self.expected_data)
            self.caculate_expect_finished = True
            return self.expected_data
 楼主| 我是人 发表于 2020-8-12 15:32
我是人 发表于 2020-8-12 10:39
我找到原因了

函数定义中的 i 需要+1

不对,这样也不对!

大家帮帮我!求求了!
 楼主| 我是人 发表于 2020-8-12 15:37
我知道了,我整错了三个缩进,就是这里最后三行的缩进,这样是正确的,就ok了。

不能粗心啊!

def caculate_expect(self):
        if (not self.caculate_expect_finished):
            self.caculate_sum()
        self.expected_data = self.data.copy()
        total_sum = self.summed_data.loc[self.col_sum_name , self.row_sum_name]
        
        for i in range(len(self.data)):
            for j in range(len(self.data.columns)):
                row_sum = self.summed_data.iloc[i][self.row_sum_name]
                col_sum = self.summed_data.loc[self.col_sum_name][j]
                self.expected_data.iloc[i,j] = row_sum * col_sum / total_sum
        self.expected_data = self.caculate_sum(self.expected_data)
        self.caculate_expect_finished = True
        return self.expected_data
ymhld 发表于 2020-8-13 23:48
python 缩进很重要
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 13:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表