Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy array partial sums with weights

I have a numpy array, say, [a,b,c,d,e,...], and would like to compute an array that would look like [x*a+y*b, x*b+y*c, x*c+y*d,...]. The idea that I have is to first split the original array into something like [[a,b],[b,c],[c,d],[d,e],...] and then attack this creature with np.average specifying the axis and weights (x+y=1 in my case), or even use np.dot. Unfortunately, I don't know how to create such array of [a,b],[b,c],... pairs. Any help, or completely different idea even to accomplish the major task, are much appreciated :-)

like image 889
Simon Righley Avatar asked Jan 12 '23 20:01

Simon Righley


1 Answers

The quickest, simplest would be to manually extract two slices of your array and add them together:

>>> arr = np.arange(5)
>>> x, y = 10, 1
>>> x*arr[:-1] + y*arr[1:]
array([ 1, 12, 23, 34])

This will turn into a pain if you want to generalize it to triples, quadruples... But you can create your array of pairs from the original array with as_strided in a much more general form:

>>> from numpy.lib.stride_tricks import as_strided

>>> arr_pairs = as_strided(arr, shape=(len(arr)-2+1,2), strides=arr.strides*2)
>>> arr_pairs
array([[0, 1],
       [1, 2],
       [2, 3],
       [3, 4]])

Of course the nice thing about using as_strided is that, just like with the array slices, there is no data copying involved, just messing with the way memory is viewed, so creating this array is virtually costless.

And now probably the fastest is to use np.dot:

>>> xy = [x, y]
>>> np.dot(arr_pairs, xy)
array([ 1, 12, 23, 34])
like image 190
Jaime Avatar answered Jan 28 '23 10:01

Jaime