如何使用多列计算Fischer精确测试?

时间:2019-03-26 22:06:12

标签: python pandas matrix p-value

我非常了解此链接: Is there a pythonic way to do a contingency table in Pandas? 将两列转换为2x2偶发性,然后轻松进行费舍尔精确测试。我正在努力的是如何采用上述解决方案并将其应用于多列。我的数据如下:

Samples A   B   C   D   E   F   G   H   I   J   K   L   M   N   0   P
AA1 1   1   0   0   1   0   0   0   1   1   0   0   1   0   0   0
AA2 1   0   1   0   0   0   0   0   1   0   1   0   0   0   0   0
AA3 1   0   1   0   0   1   0   0   1   0   1   0   0   1   0   0
AA4 0   0   0   0   1   0   0   0   0   0   0   0   1   0   0   0
AA5 0   0   0   1   0   1   0   0   0   0   0   1   0   1   0   0
AA6 1   0   0   0   1   0   0   0   1   0   0   0   1   0   0   0
AA7 1   0   0   0   0   0   0   0   1   0   0   0   0   0   0   0
AA8 1   0   0   0   1   1   0   0   1   0   0   0   1   1   0   0
AA9 0   0   0   0   1   0   0   1   0   0   0   0   1   0   0   1
AA10    1   1   1   0   1   0   0   1   1   1   1   0   1   0   0   1
AA11    1   0   1   1   0   1   0   1   1   0   1   1   0   1   0   1
AA12    1   0   1   0   0   0   1   1   1   0   1   0   0   0   1   1
AA13    0   0   0   0   1   0   1   1   0   0   0   0   1   0   1   1
AA14    1   1   0   0   0   1   1   1   1   1   0   0   0   1   1   1
AA15    1   0   0   1   0   0   1   1   1   0   0   1   0   0   1   1
AA16    0   0   0   0   1   0   1   1   0   0   0   0   1   0   1   1
AA17    1   0   0   0   0   0   1   1   1   0   0   0   0   0   1   1
AA18    1   1   1   0   0   0   0   1   1   1   1   0   0   0   0   1
AA19    1   0   0   1   1   1   0   1   1   0   0   1   1   1   0   1
AA20    0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   1
AA21    1   1   1   0   0   1   1   1   1   1   1   0   0   1   1   1
AA22    0   0   0   1   0   0   1   1   0   0   0   1   0   0   1   1
AA23    0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   1

并且我想要类似以下的输出(请注意,以下p值是假的,并不代表上述数据):

    A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P
A                                                               
B   0.05                                                            
C   0.9 0.9                                                     
D   0.4 0.8 0.8                                                 
E   0.002   0.001   0.8 0.02                                                
F   0.12    0.67    0.001   0.8 0.6                                         
G   0.9 0.9 0.8 0.01    0.8 0.8                                     
H   0.1 0.22    0.8 0.8 0.8 0.33    0.01                                    
I   0.05    0.05    0.05    0.05    0.05    0.05    0.05    0.05                                
J   0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9                         
K   0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.8 0.9 0.9                     
L   0.02    0.02    0.02    0.02    0.02    0.02    0.02    0.02    0.8 0.02    0.02                    
M   0.12    0.12    0.12    0.12    0.12    0.12    0.12    0.67    0.001   0.8 0.6 0.8             
N   0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.8 0.01    0.8 0.8 0.8         
O   0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.22    0.8 0.8 0.8 0.33    0.01    0.01        
P   0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.22    0.8 0.8 0.8 0.33    0.01    0.01    0.01    

到目前为止的代码是:

import pandas as pd
from scipy.stats import fisher_exact
df = pd.read_table("......")
df.set_index("Samples", inplace=True)
print(df.head())
print(pd.crosstab(df.A, df.B))
tab = pd.crosstab(df.A, df.B)
print(fisher_exact(tab))

这给了我2x2和p值,但是我不知道如何遍历列。像A对B,A对C,A对D ...等...等等,然后将p-val放入输出格式。

高度赞赏任何指导!

1 个答案:

答案 0 :(得分:0)

以下是完成任务的代码。

import pandas as pd
import os
from scipy.stats import fisher_exact

dirpath="...."
df = pd.read_table(".....")
df.set_index("Sample ID", inplace=True)

my_df = pd.DataFrame(index=df.columns, columns=df.columns)
for colout in df.columns:
    for colinner in df.columns:
        if(colout==colinner):
            my_df.at[colout,colinner]=0
        else:
            tab = pd.crosstab(df[colout],df[colinner])
            fish_vals = fisher_exact(tab)
            my_df.at[colout,colinner]=fish_vals[1]
my_df.to_csv(os.path.join(dirpath,'myfile.txt'), sep='\t', encoding='utf-8',quoting=0, index=True)
print(my_df)