首页 > 解决方案 > 重塑数据框并计算卡方检验的行和列的总和

问题描述

我正在研究虹膜分类数据集,并且正在尝试对其进行卡方检验。

要重建原始数据框:

from sklearn import datasets
iris = datasets.load_iris()
data = pd.DataFrame(iris.data, columns = ['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth'])
targets = pd.DataFrame(iris.target, columns=['species'])
dataset = targets.merge(data, left_index=True, right_index=True)
dataset.species = dataset.species.replace(dict(zip(range(3), iris.target_names)))
df = dataset[['species', 'SepalLength']]
df.columns = ['Species', 'SepalLengthCm']

为了对萼片长度应用卡方检验,我必须重新排列数据框,以便我的行对应于我的 3 个物种,每行都有萼片长度,每行末尾的数据总和列,和每列的总和为一行。

我使用pd.crosstab了,但我的数据的数字是列标签,数据框中的数据是数据的频率。

table = pd.crosstab(df['Species'],df['SepalLengthCm'])
SepalLengthCm  4.3  4.4  4.5  4.6  4.7  4.8  4.9  5.0  5.1  5.2  ...  6.8  \
Species                                                          ...        
setosa           1    3    1    4    2    5    4    8    8    3  ...    0   
versicolor       0    0    0    0    0    0    1    2    1    1  ...    1   
virginica        0    0    0    0    0    0    1    0    0    0  ...    2   

SepalLengthCm  6.9  7.0  7.1  7.2  7.3  7.4  7.6  7.7  7.9  
Species                                                     
setosa           0    0    0    0    0    0    0    0    0  
versicolor       1    1    0    0    0    0    0    0    0  
virginica        3    0    1    3    1    1    1    4    1  

[3 rows x 35 columns]

标签: pythonpandasdataframe

解决方案


这称为“透视”数据,可以使用以下方法完成pivot_table()

df['Id'] = df.groupby('Species').cumcount()
table = df.pivot_table(index='Species', columns='Id')
0 1 2 3 4 5 6 7 8 9 ... 40 41 42 43 44 45 46 47 48 49
濑户 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 ... 5.0 4.5 4.4 5.0 5.1 4.8 5.1 4.6 5.3 5.0
杂色 7.0 6.4 6.9 5.5 6.5 5.7 6.3 4.9 6.6 5.2 ... 5.5 6.1 5.8 5.0 5.6 5.7 5.7 6.2 5.1 5.7
弗吉尼亚 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3 6.7 7.2 ... 6.7 6.9 5.8 6.8 6.7 6.7 6.3 6.5 6.2 5.9

然后添加sum行和sum列:

table.loc['sum'] = table.sum()
table['sum'] = table.sum(axis=1)
0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49
濑户 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 ... 4.5 4.4 5.0 5.1 4.8 5.1 4.6 5.3 5.0 250.3
杂色 7.0 6.4 6.9 5.5 6.5 5.7 6.3 4.9 6.6 5.2 ... 6.1 5.8 5.0 5.6 5.7 5.7 6.2 5.1 5.7 296.8
弗吉尼亚 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3 6.7 7.2 ... 6.9 5.8 6.8 6.7 6.7 6.3 6.5 6.2 5.9 329.4
18.4 17.1 18.7 16.4 18.0 18.7 15.8 17.2 17.7 17.3 ... 17.5 16.0 16.8 17.4 17.2 17.1 17.3 16.6 16.6 876.5

请注意,要计算每个卡方统计量,您不需要创建实际的sum行和sum列。您可以使用矢量化:

df['Id'] = df.groupby('Species').cumcount()
table = df.pivot_table(index='Species', columns='Id')

chi2 = (table.sum().values * table.sum(axis=1).values[:,None]) / table.values.sum()
chi2 = pd.DataFrame(chi, index=table.index, columns=table.columns)
0 1 2 3 4 5 6 7 8 9 ... 40 41 42 43 44 45 46 47 48 49
濑户 5.254444 4.883206 5.340114 4.683309 5.140217 5.340114 4.511968 4.911763 5.054546 4.940319 ... 4.911763 4.997433 4.569082 4.797536 4.968876 4.911763 4.883206 4.940319 4.740422 4.740422
杂色 6.230599 5.790394 6.332185 5.553360 6.095151 6.332185 5.350188 5.824256 5.993565 5.858118 ... 5.824256 5.925841 5.417912 5.688808 5.891979 5.824256 5.790394 5.858118 5.621084 5.621084
弗吉尼亚 6.914957 6.426400 7.027701 6.163331 6.764632 7.027701 5.937844 6.463982 6.651888 6.501563 ... 6.463982 6.576726 6.013006 6.313657 6.539144 6.463982 6.426400 6.501563 6.238494 6.238494

推荐阅读