【问题标题】:Mapping a function with multiple inputs using numpy使用 numpy 映射具有多个输入的函数
【发布时间】: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 的下限和上限数组,但始终使用相同的meanscov_mtx

换句话说,我想要两个主要的输入数组,lower_boundslower_bounds,它们的形状都是 (1000 x 5)。然后我会经历这个过程 1000 次,计算 mvnunlower_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


【解决方案1】:

仅供参考。 不确定它是否足够有效。在我的机器上,它比 np.fromiter 结合 python map 快一点。

lower_bounds = np.full((1000,5), -np.inf)
upper_bounds = np.random.rand(1000, 5)

bounds = np.concatenate([lower_bounds, upper_bounds], axis=1)  
func1d = lambda bound: mvnun(bound[:5], bound[5:], means, cov_mtx)[0]
out = np.apply_along_axis(func1d, -1, bounds)

【讨论】:

    猜你喜欢
    • 2020-08-25
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 2018-07-01
    相关资源
    最近更新 更多