如何对熊猫数据框的行执行卡方检验?

时间:2019-01-18 11:58:19

标签: python pandas numpy scipy statistics

我有一个表格的数据框 df

          class_1_frequency    class_2_frequency
group_1          20                    10
group_2          60                    25 
..
group_n          50                    15 

假设class_1共有70个成员,class_2拥有30个成员。

对于每一行(group_1,group_2,.. group_n),我想创建列联表(最好是动态创建),然后执行chisquare test来评估p值。

例如,对于group_1,引擎盖下的列联表如下所示:

                   class_1      class_2
group_1_present      20           10
group_1_absent     70-20         30-10

此外,我知道scipy.stats.chi2_contingency()是适合chisquare的函数,但是我无法将其应用于上下文。我看过先前讨论的问题,例如:herehere

最有效的方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以利用apply上的pd.DataFrame功能。它允许将任意函数应用于DataFrame的列或行。以您的示例为例:

df = pd.DataFrame([[20, 10], [60, 25], [50, 15]])

要生成列联表,可以使用lambda和一些向量运算

>>> members = np.array([70, 30])
>>> df.apply(lambda x: np.array([x, members-x]), axis=1)
0    [[20, 10], [50, 20]]
1    [[60, 25], [10,  5]]
2    [[50, 15], [20, 15]]

这当然可以用scipy函数包装。

df.apply(lambda x: chi2_contingency(np.array([x, members-x])), axis=1)

这将产生所有可能的返回值,但是通过对输出进行切片,可以指定所需的返回值,例如预期的数组。生成的序列也可以转换为DataFrame

>>> s = df.apply(lambda x: chi2_contingency(np.array([x, members-x]))[:-1], axis=1)
>>> s
0    (0.056689342403628114, 0.8118072280034329, 1)
1                                    (0.0, 1.0, 1)
2      (3.349031920460492, 0.06724454934343391, 1)
dtype: object
>>> s.apply(pd.Series)
          0         1    2
0  0.056689  0.811807  1.0
1  0.000000  1.000000  1.0
2  3.349032  0.067245  1.0

现在我不知道这种方法的执行效率,但是我相信那些实现了这些功能的人。而且最有可能的速度并不是那么关键。但这至少是有效的,从某种意义上来说,它(假设)易于理解,并且编写速度很快。