我怎样才能让这只Pandas更快地发挥作用呢?

s4n0splo  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(138)

我试着做一个函数来求解这个方程中的n(然后是p,q和r)Equation. x,y,z,是已知的。它使用二分搜索,试图找到公差为+-0.0001的n

# game is a series with implied probabilites for each outcome in a football match
def logfunc(game):
    n_range = [1, 0]
    n = 0.5
    probs = 1 / game
        
    expression = (probs ** (1/n)).sum()
    while not math.isclose(expression, 1, abs_tol=0.0001):
        if expression > 1:
            n_range[0] = n
        else:
            n_range[1] = n 
            
        n = (n_range[0] + n_range[1]) / 2
        expression = (probs ** (1/n)).sum()
            
        
    return game[ODDS] ** (1/n)

我能够想出这个,但它是痛苦的缓慢(在一个 Dataframe 约300000行)
附加问题::)折半查找有O(log n)的大O.在这个函数中n是什么?它是0和1之间以0.0001为间隔的数字的数目吗?

72qzrwbm

72qzrwbm1#

一个大问题是使用Pandas系列通常很慢。一个更快的选择是使用Numpy数组(Pandas内部使用)。Numpy数组不像series那样标记,因此如果ODDS不是整数,则需要修改game[ODDS]表达式(在这种情况下,必须计算标签的索引)。您可以通过添加np_game = game.to_numpy()行并将变量game替换为np_game来使用Numpy数组。这在我的机器上快了25倍。如果这还不够,那么你可以使用Numba so来加速计算(因为它可以消除调用Numpy函数的开销)。这应该至少快了1个数量级。
二分查找的复杂度为O(logn)。2这个函数中的n是多少?3它是0到1之间以0. 0001为间隔的数吗?
不完全正确。如果收敛性检查直接基于n,则为真,但实际情况并非如此。该检查基于(probs ** (1/n)).sum()的收敛性,并且该表达式根本不是线性的。例如,对于提供的输入,我们针对n=0.5得到0.456n=0.250.120n=0.1250.013。请注意,最后一个值除以~10,而n除以2,而在上一步中仅除以~4。我希望此计算最初以指数速率收敛,并在O((log n)**k)中找到,其中k是一个常数,有点难以找到(当然〉=1),并且其中n实际上是以0.0001为间隔的0和1之间的数的数目。原因是该范围对于每一步具有除以2的大小,并且可以通过多项式函数来近似计算表达式。当范围变得非常小时,我希望函数是平滑的,甚至是伪线性的,所以对分搜索在最后几步应该是非常有效的,并且k应该是一个〉=1的小常数,除非probs是精心选择的,这样就不会收敛(这当然不太可能发生在随机值上,甚至可能是真实世界的值)。

相关问题