gpt4 book ai didi

python - 使用 numpy 稀疏数组优化操作

转载 作者:太空宇宙 更新时间:2023-11-04 00:28:06 24 4
gpt4 key购买 nike

我正在努力使用 python 3 进行缓慢的 numpy 操作。

我有以下操作:

np.sum(np.log(X.T * b + a).T, 1)

在哪里

(30000,1000) = X.shape
(1000,1) = b.shape
(1000,1) = a.shape

我的问题是这个操作很慢(大约 1.5 秒),而且它在一个循环中,所以它重复了大约 100 次,这使得我的代码运行时间很长。

我想知道这个函数是否有更快的实现。

可能有用的事实:X 非常稀疏(只有 0.08% 的条目非零),但它是一个 NumPy 数组。

最佳答案

我们可以优化对数运算,这似乎是瓶颈,并且可以通过 numexpr module 加快超越函数之一的速度。然后使用 NumPy sum-reduce 因为 NumPy 做得更好,因此给了我们一个混合的,就像这样 -

import numexpr as ne

def numexpr_app(X, a, b):
XT = X.T
return ne.evaluate('log(XT * b + a)').sum(0)

仔细观察广播操作:XT * b + a,我们看到有两个广播阶段,我们可以在这两个阶段进一步优化。目的是看看是否可以将其缩减为一个阶段,并且在进行一些划分后这似乎是可能的。这给了我们一个稍微修改过的版本,如下所示 -

def numexpr_app2(X, a, b):
ab = (a/b)
XT = X.T
return np.log(b).sum() + ne.evaluate('log(ab + XT)').sum(0)

运行时测试和验证

原始方法-

def numpy_app(X, a, b):
return np.sum(np.log(X.T * b + a).T, 1)

时间 -

In [111]: # Setup inputs
...: density = 0.08/100 # 0.08 % sparse
...: m,n = 30000, 1000
...: X = scipy.sparse.rand(m,n,density=density,format="csr").toarray()
...: a = np.random.rand(n,1)
...: b = np.random.rand(n,1)
...:

In [112]: out0 = numpy_app(X, a, b)
...: out1 = numexpr_app(X, a, b)
...: out2 = numexpr_app2(X, a, b)
...: print np.allclose(out0, out1)
...: print np.allclose(out0, out2)
...:
True
True

In [114]: %timeit numpy_app(X, a, b)
1 loop, best of 3: 691 ms per loop

In [115]: %timeit numexpr_app(X, a, b)
10 loops, best of 3: 153 ms per loop

In [116]: %timeit numexpr_app2(X, a, b)
10 loops, best of 3: 149 ms per loop

只是为了证明开始时所说的观察结果,即 log 部分是原始 NumPy 方法的瓶颈,这里是时间安排 -

In [44]: %timeit np.log(X.T * b + a)
1 loop, best of 3: 682 ms per loop

改进显着-

In [120]: XT = X.T

In [121]: %timeit ne.evaluate('log(XT * b + a)')
10 loops, best of 3: 142 ms per loop

关于python - 使用 numpy 稀疏数组优化操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46745617/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com