我有一个表格的数据框 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的函数,但是我无法将其应用于上下文。我看过先前讨论的问题,例如:here和here。
最有效的方法是什么?
答案 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
现在我不知道这种方法的执行效率,但是我相信那些实现了这些功能的人。而且最有可能的速度并不是那么关键。但这至少是有效的,从某种意义上来说,它(假设)易于理解,并且编写速度很快。