首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从pandas DataFrame计算pvalue

从pandas DataFrame计算pvalue
EN

Stack Overflow用户
提问于 2018-05-02 22:23:15
回答 1查看 13.8K关注 0票数 6

我有一个多索引的DataFrame统计数据和8个样本(这里只显示了两个)和每个样本的8个基因。

代码语言:javascript
复制
 In[13]:stats
    Out[13]: 
                       ARG/16S                                            \
                         count          mean           std           min   
    sample      gene                                                       
    Arnhem      IC        11.0  2.319050e-03  7.396130e-04  1.503150e-03   
                Int1      11.0  7.243040e+00  6.848327e+00  1.364879e+00   
                Sul1      11.0  3.968956e-03  9.186019e-04  2.499074e-03   
                TetB       2.0  1.154748e-01  1.627663e-01  3.816936e-04   
                TetM       4.0  1.083125e-04  5.185259e-05  5.189226e-05   
                blaOXA     4.0  4.210963e-06  3.783235e-07  3.843571e-06   
                ermB       4.0  4.111081e-05  7.894879e-06  3.288865e-05   
                ermF       4.0  2.335210e-05  4.519758e-06  1.832037e-05   
    Basel       Aph3a      4.0  7.815592e-06  1.757242e-06  5.539389e-06   
                IC        11.0  5.095161e-03  5.639278e-03  1.302205e-03   
                Int1      12.0  1.333068e+01  1.872207e+01  4.988048e-02   
                Sul1      11.0  1.618617e-02  1.988817e-02  2.970397e-03   

我试图计算每个样本的p值(学生t检验),比较它们之间的每个基因。

我使用了scipy.stats.ttest_ind_from_stats,但我设法获得了一个基因的不同样本的p值,并且只获得了彼此相邻的那些样本的p值。

代码语言:javascript
复制
Experiments = list(values1_16S['sample'].unique())
for exp in Experiments:
    if Experiments.index(exp)<len(Experiments)-1:
        second = Experiments[Experiments.index(exp)+1]
    else:
        second = Experiments[0]
    tstat, pvalue = scipy.stats.ttest_ind_from_stats(stats.loc[(exp,'Sul1')]['ARG/16S','mean'],
                                    stats.loc[(exp,'Sul1')]['ARG/16S','std'],
                                    stats.loc[(exp,'Sul1')]['ARG/16S','count'],
                                    stats.loc[(second,'Sul1')]['ARG/16S','mean'],
                                    stats.loc[(second,'Sul1')]['ARG/16S','std'],
                                    stats.loc[(second,'Sul1')]['ARG/16S','count'])
    d.append({'loc1':exp, 'loc2':second, 'pvalue':pvalue})


stats_Sul1 = pd.DataFrame(d)
stats_Sul1

如何获得所有样本之间的p值?有没有一种方法可以一次为所有基因做这件事,而不是为每个基因逐个运行代码?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-03 04:43:49

假设你对Y样本有相同的X基因。我用X=3和Y=2尝试了我的方法,但我想你可以推广一下。我从以下几点开始:

代码语言:javascript
复制
df1 = 
             count       mean        std       min
sample gene                                       
Arnhem IC       11   0.002319   0.000740  0.001503
       Int1     11   7.243040   6.848327  1.364879
       Sul1     11   0.003969   0.000919  0.002499
Basel  IC       11   0.005095   0.005639  0.001302
       Int1     12  13.330680  18.722070  0.049880
       Sul1     11   0.016186   0.019888  0.002970

请注意,这些基因需要处于相同的顺序。使用df_reindex = df1.reset_index()的第一个reset_index(),我不确定我正在做的事情是否可以使用多索引:

代码语言:javascript
复制
df_reindex =
   sample  gene  count       mean        std       min
0  Arnhem    IC     11   0.002319   0.000740  0.001503
1  Arnhem  Int1     11   7.243040   6.848327  1.364879
2  Arnhem  Sul1     11   0.003969   0.000919  0.002499
3   Basel    IC     11   0.005095   0.005639  0.001302
4   Basel  Int1     12  13.330680  18.722070  0.049880
5   Basel  Sul1     11   0.016186   0.019888  0.002970

我创建了一个滚动的DF并将其连接到df_reindex

代码语言:javascript
复制
nb_genes = 3
df_rolled = pd.DataFrame(pd.np.roll(df_reindex,nb_genes,0), columns = df_reindex.columns)
df_joined = df_reindex.join(df_rolled, rsuffix='_')
# rsuffix='_' is to be able to perform the join

现在,在同一行上,我有了计算pvalue和使用apply创建列所需的所有数据

代码语言:javascript
复制
df_joined['pvalue'] = df_joined.apply(lambda x: stats.ttest_ind_from_stats(x['mean'],x['std'],x['count'], x['mean_'],x['std_'],x['count_'])[1],axis=1)

最后,我创建了一个包含所需数据的DF并重命名列:

代码语言:javascript
复制
df_output = df_joined[['sample','sample_','gene','pvalue']].rename(columns = {'sample':'loc1', 'sample_':'loc2'})

你最终得到了数据:

代码语言:javascript
复制
df_output = 
     loc1    loc2  gene    pvalue
0  Arnhem   Basel    IC  0.121142
1  Arnhem   Basel  Int1  0.321072
2  Arnhem   Basel  Sul1  0.055298
3   Basel  Arnhem    IC  0.121142
4   Basel  Arnhem  Int1  0.321072
5   Basel  Arnhem  Sul1  0.055298

您可以根据需要重新编制索引。

如果你想对每个样本都这样做,我认为循环for可以做到这一点。

编辑:使用pivot_table编辑,我认为有一种更简单的方法。

将您的输入stats作为仅用于ARG/16S的多索引表(不确定如何处理此级别),因此我从(可能是您的stats['ARG/16S'])开始:

代码语言:javascript
复制
df=
               count       mean           std       min
sample gene                                            
Arnhem IC         11   0.002319  7.396130e-04  0.001503
       Int1       11   7.243040  6.848327e+00  1.364879
       Sul1       11   0.003969  9.186019e-04  0.002499
       TetB        2   0.115475  1.627663e-01  0.000382
       TetM        4   0.000108  5.185259e-05  0.000052
       blaOXA      4   0.000004  3.783235e-07  0.000004
       ermB        4   0.000041  7.894879e-06  0.000033
       ermF        4   0.000023  4.519758e-06  0.000018
Basel  Aph3a       4   0.000008  1.757242e-06  0.000006
       IC         11   0.005095  5.639278e-03  0.001302
       Int1       12  13.330680  1.872207e+01  0.049880
       Sul1       11   0.016186  1.988817e-02  0.002970

使用函数pivot_table,您可以重新排列数据,如下所示:

代码语言:javascript
复制
df_pivot = df.pivot_table(values = ['count','mean','std'], index = 'gene', 
                               columns = 'sample', fill_value = 0)

在这个df_pivot中(为了提高可读性,我不在这里打印它,但在末尾显示新的列),您可以使用itertoolsapply为每对(sample1、sample2)创建一个列

代码语言:javascript
复制
import itertools
for sample1, sample2 in itertools.combinations(df.index.levels[0],2):
    # itertools.combinations create all combinations between your samples
    df_pivot[sample1+ '_' + sample2 ] = df_pivot.apply(lambda x: stats.ttest_ind_from_stats(x['mean'][sample1],x['std'][sample1],x['count'][sample1], 
                                                                                        x['mean'][sample2 ],x['std'][sample2 ],x['count'][sample2 ],)[1],axis=1).fillna(1)

我认为这种方法与样本数量和基因无关,如果基因不完全相同,你最终得到的df_pivot如下:

代码语言:javascript
复制
        count            mean                      std            Arnhem_Basel
sample Arnhem Basel    Arnhem      Basel        Arnhem      Basel             
gene                                                                          
Aph3a       0     4  0.000000   0.000008  0.000000e+00   0.000002     1.000000
IC         11    11  0.002319   0.005095  7.396130e-04   0.005639     0.121142
Int1       11    12  7.243040  13.330680  6.848327e+00  18.722070     0.321072
Sul1       11    11  0.003969   0.016186  9.186019e-04   0.019888     0.055298
TetB        2     0  0.115475   0.000000  1.627663e-01   0.000000     1.000000
TetM        4     0  0.000108   0.000000  5.185259e-05   0.000000     1.000000
blaOXA      4     0  0.000004   0.000000  3.783235e-07   0.000000     1.000000
ermB        4     0  0.000041   0.000000  7.894879e-06   0.000000     1.000000
ermF        4     0  0.000023   0.000000  4.519758e-06   0.000000     1.000000

如果有效,请让我知道

EDIT2:回复评论,我认为你可以这样做:

不更改df_pivot,然后创建一个多索引DF df_multi来写入结果:

代码语言:javascript
复制
df_multi = pd.DataFrame(index = df.index.levels[1], 
                        columns = pd.MultiIndex.from_tuples([p for p in itertools.combinations(df.index.levels[0],2)])).fillna(0)

然后使用循环for实现此df_multi中的数据

代码语言:javascript
复制
for sample1, sample2 in itertools.combinations(df.index.levels[0],2):
    # itertools.combinations create all combinations between your samples
    df_multi.loc[:,(sample1,sample2)] = df_pivot.apply(lambda x: stats.ttest_ind_from_stats(x['mean'][sample1],x['std'][sample1],x['count'][sample1], 
                                                                                        x['mean'][sample2 ],x['std'][sample2 ],x['count'][sample2 ],)[1],axis=1).fillna(1)

最后,您可以在level 1上使用transposeunstack来获得您所要求的方式(如果我误解了,请关闭)

代码语言:javascript
复制
df_output = df_multi.transpose().unstack(level=[1]).fillna(1)

您将看到,索引中没有最后一个样本,列中没有第一个样本(因为它们不存在,我是按照我构建所有内容的方式构建的)。如果需要的话,您需要在创建df_multi和循环for (我没有尝试过,但它应该可以工作)中将itertools.combinations替换为itertools.combinations_with_replacement

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50137024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档