Python-在大型数据集上计算多项式概率密度函数?

Python-在大型数据集上计算多项式概率密度函数?,python,data-structures,Python,Data Structures,我最初打算使用MATLAB来解决这个问题,但是内置函数有一些不适合我的目标的限制。同样的限制也发生在NumPy中 我有两个以制表符分隔的文件。第一个文件显示蛋白质结构内部数据库的氨基酸残基、频率和计数,即 A 0.25 1 S 0.25 1 T 0.25 1 P 0.25 1 第二个文件由四组氨基酸和它们出现的次数组成,即 ASTP 1 注意,有超过8000个这样的四胞胎 基于每个氨基酸出现的背景频率和四胞胎的计数,我的目标是计算每个四胞

我最初打算使用MATLAB来解决这个问题,但是内置函数有一些不适合我的目标的限制。同样的限制也发生在NumPy中

我有两个以制表符分隔的文件。第一个文件显示蛋白质结构内部数据库的氨基酸残基、频率和计数,即

A    0.25    1
S    0.25    1
T    0.25    1
P    0.25    1
第二个文件由四组氨基酸和它们出现的次数组成,即

ASTP    1
注意,有超过8000个这样的四胞胎

基于每个氨基酸出现的背景频率和四胞胎的计数,我的目标是计算每个四胞胎的多项式概率密度函数,然后将其用作最大似然计算中的期望值

多项式分布如下所示:

f(x|n, p) = n!/(x1!*x2!*...*xk!)*((p1^x1)*(p2^x2)*...*(pk^xk))
式中,x是n个试验中k个结果的数量,具有固定概率p。在我的计算中,n在所有情况下都是4

我创建了四个函数来计算这个分布

# functions for multinomial distribution


def expected_quadruplets(x, y):
    expected = x*y
    return expected

# calculates the probabilities of occurence raised to the number of occurrences

def prod_prob(p1, a, p2, b, p3, c, p4, d):
    prob_prod = (pow(p1, a))*(pow(p2, b))*(pow(p3, c))*(pow(p4, d))
    return prob_prod 


# factorial() and multinomial_coefficient() work in tandem to calculate C, the multinomial coefficient

def factorial(n):
    if n <= 1:
        return 1
    return n*factorial(n-1)


def multinomial_coefficient(a, b, c, d):
    n = 24.0
    multi_coeff =  (n/(factorial(a) * factorial(b) * factorial(c) * factorial(d)))
    return multi_coeff
我最初打算在嵌套for循环中调用这些函数,但这会导致运行时错误或溢出错误。我知道我可以重置递归限制,但我更愿意更优雅地执行此操作

我有以下几点:

for i in quadruplets:
    quad = i[0].split(' ')
    for j in amino_acids:
        for k in quadruplets:
            for v in k:
                if j[0] == v:
                    multinomial_coefficient(int(j[2]), int(j[2]), int(j[2]), int(j[2]))
我还没有真正了解如何合并其他函数。我认为我目前的嵌套列表安排是次优的

我希望将字符串“ASTP”中的每个字母与氨基酸中每个子列表的第一个成分进行比较。如果存在匹配项,我希望使用索引将适当的数值传递给函数

他们的方法更好吗?我是否可以将每个氨基酸和四联体的适当数字附加到循环中的临时数据结构中,将其传递给函数并在下一次迭代中清除它


谢谢,S:-)

这可能与您最初的问题无关,但我强烈建议不要因为溢出而显式计算阶乘。相反,利用这样一个事实,即
factorial(n)
=
gamma(n+1)
,使用gamma函数的对数,使用加法而不是乘法,使用减法而不是除法
scipy.special
包含一个名为
gammaln
的函数,该函数提供gamma函数的对数

from itertools import izip
from numpy import array, log, exp
from scipy.special import gammaln

def log_factorial(x):
    """Returns the logarithm of x!
    Also accepts lists and NumPy arrays in place of x."""
    return gammaln(array(x)+1)

def multinomial(xs, ps):
    n = sum(xs)
    xs, ps = array(xs), array(ps)
    result = log_factorial(n) - sum(log_factorial(xs)) + sum(xs * log(ps))
    return exp(result)
如果您不想仅仅为了
gammaln
而安装SciPy,这里有一个纯Python的替代品(当然它速度较慢,并且不像SciPy中的那样进行矢量化):

然后,您可以通过以下方式查找频率或计数:

freq_A = amino_acid_dict["A"][1]
count_A = amino_acid_dict["A"][2]
这样可以在主循环中节省一些时间:

for quadruplet in quadruplets:
    probs = [amino_acid_dict[aa][1] for aa in quadruplet]
    counts = [amino_acid_dict[aa][2] for aa in quadruplet]
    print quadruplet, multinomial(counts, probs)

非常有用的答案,但我认为你的最后一行应该是(n,计数,概率)?另外,“n”是多余的,因为它总是计数的总和吗?是的,你是对的,谢谢-我已经修正了我的答案。
amino_acid_dict = dict((amino_acid[0], amino_acid) for amino_acid in amino_acids)
print amino_acid_dict
{"A": ["A", 0.25, 1], "S": ["S", 0.25, 1], "T": ["T", 0.25, 1], "P": ["P", 0.25, 1]}
freq_A = amino_acid_dict["A"][1]
count_A = amino_acid_dict["A"][2]
for quadruplet in quadruplets:
    probs = [amino_acid_dict[aa][1] for aa in quadruplet]
    counts = [amino_acid_dict[aa][2] for aa in quadruplet]
    print quadruplet, multinomial(counts, probs)