【发布时间】:2018-12-30 09:45:11
【问题描述】:
我正在尝试有效地评估一个接受 4 个参数的 python 函数的多个实例,但我找不到如何以不涉及本机 python 的慢 for 循环的方式将该函数映射到多个输入值.
这是我只调用一次函数的示例(即一次观察)。
from scipy.stats.mvn import mvnun
lower_bounds_one_obs = np.full(5, -1)
upper_bounds_one_obs = np.full(5, 1)
cov_mtx = np.eye(5)
means = np.zeros(5)
single_result = mvnun(lower_bounds_one_obs, upper_bounds_one_obs, means, cov_mtx)[0]
print(single_result)
为了上下文,mvnun 函数计算上下界之间的多元正态分布的矩形 CDF。在这种特定情况下,下限和上限包含 5 个元素。
我想做的是计算mvnun 的下限和上限数组,但始终使用相同的means 和cov_mtx。
换句话说,我想要两个主要的输入数组,lower_bounds 和 lower_bounds,它们的形状都是 (1000 x 5)。然后我会经历这个过程 1000 次,计算 mvnun 为 lower_bounds[0] 和 upper_bounds[0],然后是 lower_bounds[1] 和 upper_bounds[1],依此类推,直到 lower_bounds[999] 和 upper_bounds[999]。
在 scipy 的文档中,我发现我可以对这个函数进行矢量化/映射,但仅限于上限,使下限固定。可以这样做:
lower_fixed = np.full(5, -np.inf)
upper_bounds = np.random.rand(5 * 1000).reshape((1000, 5))
func1d = lambda upper_slice: mvnun(lower_fixed, upper_slice, means, cov_mtx)[0]
out = np.apply_along_axis(func1d, -1, upper_bounds)
这样,mvnun 会在 固定 下限的情况下被多次评估,并遍历 upper_bound 的所有 1000 行。
有谁知道如何调整上面代码的 sn-p 以便我可以使用 array 的下限而不是固定的下限?
谢谢!
PS:这个问题是this 的一点更新。 here 也有一些有趣的见解,但他们提出的解决方案非常慢,因为它们使用常规的 python 循环。还有更多想法here。
【问题讨论】:
-
1) numpy.vectorize 或诸如 lambda upper_slice np.apply_along_axis(...) 之类的东西不会提高性能,如果这是你不想要的,这些东西在 Python for 循环中调用 Python 函数。它们是为了方便而不是为了性能。 2)您的测试示例受编译的 mvdst.f 的限制,包装器在这里无关紧要。解决方案:使用 Intel-scipy(我遇到了 3 倍加速)和一些多处理,或者包装 fortran 子例程 yourdelf(快速 Fortran 编译器,例如需要 ifort)并使用 cython 编写实现(相当多的工作)
标签: python function numpy mapping vectorization