【发布时间】:2017-10-22 21:19:03
【问题描述】:
我想有效地将复杂的函数应用于 Python 中的矩阵行(编辑:Python 3)。在 R 中,这是 apply 函数和它的近亲,它工作得很快。
在 Python 中,我知道这可以通过几种方式完成。列表理解、numpy.apply_along_axis、panas.dataframe.apply。
在我的编码中,这些 Python 方法非常慢。我应该使用另一种方法吗?或者也许我对这些 Python 方法的实现不正确?
这是一个例子。数学取自概率回归模型。要明确我的目标不是执行概率回归,我对一种有效的应用方法很感兴趣。
在 R 中:
> n = 100000
> p = 7
> x = matrix(rnorm(700000, 0 , 2), ncol = 7)
> beta = rep(1, p)
> start <- Sys.time()
> test <- apply(x, 1, function(t)(dnorm(sum(t*beta))*sum(t*beta)/pnorm(sum(t*beta))) )
> end <- Sys.time()
> print(end - start)
Time difference of 0.6112201 secs
在 Python 中通过理解:
import numpy as np
from scipy.stats import norm
import time
n = 100000
p = 7
x = norm.rvs(0, 2, n * p)
x = x.reshape( (n , p) )
beta = np.ones(p)
start = time.time()
test = [
norm.pdf(sum(x[i,]*beta))*sum(x[i,]*beta)/norm.cdf(sum(x[i,]*beta))
for i in range(100000) ]
end = time.time()
print (end - start)
23.316735982894897
在 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
在this 问题中,最受好评的回答指出 apply_along_axis 不是为了速度。所以我不包括这种方法。
同样,我对快速执行这些计算很感兴趣。非常感谢您的帮助!
【问题讨论】:
-
python 2 还是 python 3?在 python 2 中,避免使用
range(100000),因为它必须分配列表,请改用xrange。在您的特殊情况下,避免两者都支持[norm.pdf(sum(x_*beta))*sum(x_*beta)/norm.cdf(sum(x_*beta)) for x_ in x.transpose()]。你真正想要的可能是用 numpy 构造一个 ufunc。 -
你为什么要单点评估pdf、cdf?
-
我想推荐cupy?所需的 CUDA 库和支持 CUDA 的 GPU...
-
@percusse 这个表达式是概率回归模型的可能性梯度的一部分。我知道库可以为我执行概率回归,但这个表达式说明了我想要做的计算类型。
标签: python r numpy list-comprehension apply