如何有效地使用numpy进行迭代求和

时间:2014-01-23 13:39:31

标签: python numpy cython

问题的定义

我可以表达我想解决的问题:

给定A [Nx1]和n [Nx1]和x [Mx1],我想执行此操作

S = sum([A[i]*x**n[i] for i in range(len(n))])

使用numpy。我想我可以使用像numpy中的广播这样的东西来做这件事,但我无法弄清楚numpy docs。有人可以帮我弄清楚如何在numpy中有效地做到这一点吗?

我有一个解决这个问题的cython解决方案非常快,我想知道我是否可以使用numpy更容易地完成它并完全避免cython。

Cython解决方案

这是使用cython来演示此问题的一个有效实现:

cimport cython
import numpy as np

@cython.boundscheck(False)
cpdef  sum_function( double [:] A, double [:] x, double [:] n, double [:] out):
    cdef int i,j
    cdef int Nx = len(x)
    cdef int Nn = len(n)

    out[:] = 0

    for i in xrange(Nx):
        for j in range(Nn):
            out[i] += A[j]*x[i]**n[j]

2 个答案:

答案 0 :(得分:3)

您可以使用np.sum(A * x.reshape(-1, 1)**n, axis=1)

In [40]: A
Out[40]: array([ 1.,  2., -1.,  3.])

In [41]: n
Out[41]: array([ 2.,  1.,  1.,  3.])

In [42]: x
Out[42]: array([  5.,  10.,   1.])

In [43]: S = sum([A[i]*x**n[i] for i in range(len(n))])

In [44]: S
Out[44]: array([  405.,  3110.,     5.])

In [45]: np.sum(A * x.reshape(-1, 1)**n, axis=1)
Out[45]: array([  405.,  3110.,     5.])

x.reshape(-1, 1)具有形状(3,1),n具有形状(4,),因此x.reshape(-1, 1)**n的(广播)结果具有形状(3,4);列 k 包含x**n[k]A具有形状(4,),因此A * x.reshape(-1, 1)**n具有形状(3,4);该产品的元素(i,j)包含A[j]*x[i]**n[j]。期望的结果是axis=1上此数组的总和。

这是具有相同数据的cython版本:

In [46]: out = np.zeros_like(x)

In [47]: sum_function(A, x, n, out)

In [48]: out
Out[48]: array([  405.,  3110.,     5.])

答案 1 :(得分:0)

广播只有在M = N或x是标量时才有效。如果M> N,只是做

S = sum(a*x[:N]**n)

类似地,对于M< Ñ