python - 来自 Pandas Dataframe 的 Fishers 精确测试

标签 python python-3.x pandas statistics combinations

我正在尝试找出使用数据框中四列的 Fisher 精确检验创建 p 值的最佳方法。我已经提取了列联表的四个部分,“a”是左上角,“b”是右上角,“c”是左下角,“d”是右下角。我已经开始通过简单的 pandas 计算包括额外的计算列,但如果有更简单的方法只使用 4 个初始列,则这些列不是必需的。当包括一个额外的集(x.type = high)时,我有超过 100 万行,所以想使用一种有效的方法。到目前为止,这是我的代码:

import pandas as pd
import glob
import math
path = r'directory_path'
all_files = glob.glob(path + "/*.csv")
li = []

for filename in all_files:
    df = pd.read_csv(filename, index_col=None, header=0)
    li.append(df)

frame = pd.concat(li, axis=0, ignore_index=True)
frame['a+b'] = frame['a'] + frame['b']
frame['c+d'] = frame['c'] + frame['d']
frame['a+c'] = frame['a'] + frame['c']
frame['b+d'] = frame['b'] + frame['d']

作为此数据的示例,“frame”当前显示:

    ID(n)   a   b   c   d   i   x.name  x.type  a+b     c+d     a+c     b+d
0   1258065     5   28  31  1690    1754    Albumin     low     33  1721    36  1718
1   1132105     4   19  32  1699    1754    Albumin     low     23  1731    36  1718
2   898621  4   30  32  1688    1754    Albumin     low     34  1720    36  1718
3   573158  4   30  32  1688    1754    Albumin     low     34  1720    36  1718
4   572975  4   23  32  1695    1754    Albumin     low     27  1727    36  1718
...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...
666646  12435   1   0   27  1726    1754    WHR     low     1   1753    28  1726
666647  15119   1   0   27  1726    1754    WHR     low     1   1753    28  1726
666648  17053   1   2   27  1724    1754    WHR     low     3   1751    28  1726
666649  24765   1   3   27  1723    1754    WHR     low     4   1750    28  1726
666650  8733    1   1   27  1725    1754    WHR     low     2   1752    28  1726

最好的方法是将它们转换为 numpy 数组并通过迭代对其进行处理,还是将其保存在 pandas 中?我假设我不能在数据框中使用数学函数(我试过 math.comb(),但它在数据框中不起作用)。我也试过使用 pyranges因为它的 fisher 方法,但它似乎不适用于我的环境(python 3.8)。

如有任何帮助,我们将不胜感激!

最佳答案

answer here 之后来自 pyranges 的作者(我认为),假设你的数据是这样的:

import pandas as pd 
import scipy.stats as stats
import numpy as np

np.random.seed(111)
df = pd.DataFrame(np.random.randint(1,100,(1000000,4)))
df.columns=['a','b','c','d']
df['ID'] = range(1000000)

df.head()

    a   b   c   d   ID
0   85  85  85  87  0
1   20  42  67  83  1
2   41  72  58  8   2
3   13  11  66  89  3
4   29  15  35  22  4

你把它转换成一个 numpy 数组,然后像帖子中那样做:

c = df[['a','b','c','d']].to_numpy(dtype='uint64')

from fisher import pvalue_npy

_, _, twosided = pvalue_npy(c[:, 0], c[:, 1], c[:, 2], c[:, 3])
df['odds'] = (c[:, 0] * c[:, 3]) / (c[:, 1] * c[:, 2])

df['pvalue'] = twosided

或者你可以直接拟合:

_, _, twosided = pvalue_npy(df['a'].to_numpy(np.uint), df['b'].to_numpy(np.uint), 
                            df['c'].to_numpy(np.uint), df['d'].to_numpy(np.uint))

df['odds'] = (df['a'] * df['d']) / (df['b'] * df['c'])
df['pvalue'] = twosided

关于python - 来自 Pandas Dataframe 的 Fishers 精确测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64134929/

相关文章:

python-3.x - 我想将国家列表与列数据进行比较,列数据是 pandas 数据框 Python 中的字典对象类型

python - 向 Pandas 数据透视表添加过滤器

python - 如何根据 Pandas 数据框的条件增加计数器?

python - 使用 Python 3 的平均年龄计算器

python:检查一个键中一定数量的字符是否与同一字典中另一个键的字符匹配

python - 如何从python中的字符串中提取一定长度的数字?

python - 尽管所有图像都可下载,但请求无法从某个站点下载任何图像?

python - 从 IP 地址获取子网

Python 创建一个包含打乱元素并按对象引用的子列表

python - 如何允许自定义类参数在 ipython 中以制表符完成?