Python/numpy:最有效的方法是对数组中的n个元素求和,以便每个输出元素是前n个输入元素的总和?

我想编写一个函数,它将一个扁平数组作为输入,并返回一个等长的数组,其中包含输入数组中前n个元素的总和,输出数组的初始n-1个元素设置为NaN.

例如,如果数组有十个元素= [2,4,3,7,6,1,9,4,6,5]
然后n = 3,则得到的阵列应为[NaN,NaN,9,14,16,14,16,14,19,15].

我想出了这样做的一种方法:

def sum_n_values(flat_array, n): 

    sums = np.full(flat_array.shape, np.NaN)
    for i in range(n - 1, flat_array.shape[0]):
        sums[i] = np.sum(flat_array[i - n + 1:i + 1])
    return sums

是否有更好/更有效/更“Pythonic”的方式来做到这一点?

在此先感谢您的帮助.

最佳答案
你可以使用np.cumsum,并采用cumsumed数组和它的移位版本的区别:

n = 3
arr = np.array([2, 4, 3, 7, 6, 1, 9, 4, 6, 5])
sum_arr = arr.cumsum()
shifted_sum_arr = np.concatenate([[np.NaN]*(n-1), [0],  sum_arr[:-n]])
sum_arr
=> array([ 2,  6,  9, 16, 22, 23, 32, 36, 42, 47])
shifted_sum_arr
=> array([ nan,  nan,   0.,   2.,   6.,   9.,  16.,  22.,  23.,  32.])
sum_arr - shifted_sum_arr
=> array([ nan,  nan,   9.,  14.,  16.,  14.,  16.,  14.,  19.,  15.])

IMO,这是一种更加努力的方式,主要是因为它避免了循环.

计时

def cumsum_app(flat_array, n):
    sum_arr = flat_array.cumsum()
    shifted_sum_arr = np.concatenate([[np.NaN]*(n-1), [0],  sum_arr[:-n]])
    return sum_arr - shifted_sum_arr

flat_array = np.random.randint(0,9,(100000))
%timeit cumsum_app(flat_array,10)
1000 loops, best of 3: 985 us per loop
%timeit cumsum_app(flat_array,100)
1000 loops, best of 3: 963 us per loop

转载注明原文:Python/numpy:最有效的方法是对数组中的n个元素求和,以便每个输出元素是前n个输入元素的总和? - 代码日志