Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中R应用的匹配速度_Python_R_Numpy_List Comprehension_Apply - Fatal编程技术网

Python中R应用的匹配速度

Python中R应用的匹配速度,python,r,numpy,list-comprehension,apply,Python,R,Numpy,List Comprehension,Apply,我想高效地将一个复杂的函数应用于Python中矩阵的行(编辑:Python 3)。在R中,这是apply函数及其近亲,它工作得很快 在Python中,我理解这可以通过几种方式实现。列表理解,numpy.apply_沿_轴,panas.dataframe.apply 在我的编码中,这些Python方法非常慢。我是否应该使用其他方法?或者我对这些Python方法的实现是不正确的 这里有一个例子。该数学模型取自概率回归模型。明确地说,我的目标不是执行概率回归,我对一种有效的应用方法感兴趣 在R中: 在

我想高效地将一个复杂的函数应用于Python中矩阵的行(编辑:Python 3)。在R中,这是apply函数及其近亲,它工作得很快

在Python中,我理解这可以通过几种方式实现。列表理解,numpy.apply_沿_轴,panas.dataframe.apply

在我的编码中,这些Python方法非常慢。我是否应该使用其他方法?或者我对这些Python方法的实现是不正确的

这里有一个例子。该数学模型取自概率回归模型。明确地说,我的目标不是执行概率回归,我对一种有效的应用方法感兴趣

在R中:

在Python中,通过pandas.dataframe.apply:

frame = DataFrame(x)
f = lambda t: norm.pdf(sum(t))*sum(t)/norm.cdf(sum(t))
start = time.time()
test = frame.apply(f, axis = 1)
end = time.time()
print(end - start)
34.39404106140137
在这个问题上,多数被投票赞成的人指出,沿_轴应用_不是为了速度。因此,我不包括这种方法


同样,我对快速执行这些计算感兴趣。我真的很感谢你的帮助

列表理解使用python级别的循环,效率非常低。您应该修改代码以利用numpy矢量化。如果在
time.time()
调用

xbeta = np.sum(x * beta, axis=1)
test = norm.pdf(xbeta) * xbeta / norm.cdf(xbeta)
你会看到巨大的不同。对于我的机器,它在0.02秒内完成。 我已经用你的列表理解测试了它,它们都给出了相同的结果


xbeta
是在计算过程中浪费计算多次的东西。通过沿第二轴求和,我们将其折叠为1D数组,即100000行。现在所有的计算都处理1D数组,所以我们让numpy来处理其余的部分。

这似乎就是您想要的:

y = np.dot(x, beta)
test2 = norm.pdf(y) * y / norm.cdf(y)

# let's compare it to the expected output:
np.allclose(test2, np.array(test))
True
这将计算“测试”列表中的所有100000个值(在数字公差范围内),但根据ipython的说法,运行时间约为11.5毫秒:

%time y = np.dot(x, beta); test2 = norm.pdf(y) * y / norm.cdf(y)
CPU times: user 10 ms, sys: 0 ns, total: 10 ms
Wall time: 15.2 ms
这将通过以下方式改进您的版本:

  • 消除常见的
    和(x[i,]*beta)
    表达式
  • 将循环从i=0到100000矢量化为点积
  • 在这两者中,第二个更为重要


    我还注意到,上面的代码使用了
    sum
    ,它是python内置的,可以在任何迭代器上求和。您几乎可以肯定应该使用
    np.sum
    ,这是numpy矢量化版本专门用于numpy数组的。我不得不将此作为旁白,因为一旦我以“批处理”的形式重写代码,
    sum
    就隐含在点积中,因此
    np.sum
    不会出现在最终版本中。

    python 2或python 3?在python 2中,避免使用
    range(100000)
    ,因为它必须分配列表,所以使用
    xrange
    。在您的特殊情况下,避免使用
    [norm.pdf(sum(x_*beta))*sum(x_*beta)/norm.cdf(sum(x_*beta))作为x.In x.transpose()]
    。你真正想要的可能是用numpy构建一个ufunc。为什么你要在一个点上评估pdf,cdf?我想建议一下?必需的CUDA库和支持CUDA的GPU…@percusse此表达式是概率回归模型可能性梯度的一部分。我知道库可以为我执行probit回归,但这个表达式说明了我希望执行的计算类型。另请参见一个相关问题。实际上,R中的apply family是引擎盖下的循环,可以说没有矢量化:。@Parfait感谢您的评论,因为我不知道R。我只是将其行为比作numpy。那么,我的理解是否正确,即
    apply
    使用R级循环,但它们恰好比纯Python更有效?请参见上面的链接,特别是apply只是在C级运行循环但调用R级函数的隐藏循环(类似R的Python是在C和一些Fortran之上编写的)。Vectorzied被松散地定义为仅机器级计算。@Parfait是的,我的意思是专门针对
    apply
    ,而不是*apply系列。Hmmm…比较您和OP的numpy和pandas,
    np.all()
    返回False。@Parfait,OP以两种不同的方式解决了相同的问题,只是对pandas进行了实验,看看它是否更快(不是。)根本没有理由使用pandas,所以我们应该忽略这一部分。我将我的代码计算的
    test2
    与上面几行python列表计算的第一个
    test
    列表进行比较。正确。我比较了您的test2和OP的测试以及
    np.all()
    不会返回True。是吗?在我的机器上它完全相等,但我猜它可能对浮点舍入很敏感。
    np.allclose(test2,np.array(test))
    在你的机器上说了什么?或者如果没有这个功能,
    np.mean有多大(np.abs(test2 np.array(test))
    ?现在我用
    np.allclose()实现了
    差别很小:
    3.60353489474e-14
    。我使用的是ubuntu 64位/python 3.5/numpy 1.12.1
    y = np.dot(x, beta)
    test2 = norm.pdf(y) * y / norm.cdf(y)
    
    # let's compare it to the expected output:
    np.allclose(test2, np.array(test))
    True
    
    %time y = np.dot(x, beta); test2 = norm.pdf(y) * y / norm.cdf(y)
    CPU times: user 10 ms, sys: 0 ns, total: 10 ms
    Wall time: 15.2 ms