Partial amounts of a numpy array with weights

I have a numpy array, say, [a,b,c,d,e,...]and would like to compute an array that will 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 the help of np.averageindicating the axis and weight ( x+y=1in my case) or even use it np.dot. Unfortunately, I do not know how to create such an array of pairs [a,b],[b,c],.... Any help or a completely different idea even for solving the main problem is very welcome :-)

+4
source share
4 answers

The easiest, easiest way is to manually extract two fragments 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 own array of pairs from the original array using as_stridedin 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 it as_stridedis that, as in the case of arrays, there is no data copying, just messing with how the memory is viewed, so creating this array is practically cost-effective.

And now, probably the fastest is using np.dot:

>>> xy = [x, y]
>>> np.dot(arr_pairs, xy)
array([ 1, 12, 23, 34])
+5
source

It looks like a correlate problem .

a
Out[61]: array([0, 1, 2, 3, 4, 5, 6, 7])

b
Out[62]: array([1, 2])

np.correlate(a,b,mode='valid')
Out[63]: array([ 2,  5,  8, 11, 14, 17, 20])

BLAS , :

arr = np.random.rand(1E6)

b = np.random.rand(2)

np.allclose(jamie_dot(arr,b),np.convolve(arr,b[::-1],mode='valid'))
True

%timeit jamie_dot(arr,b)
100 loops, best of 3: 16.1 ms per loop

%timeit np.correlate(arr,b,mode='valid')
10 loops, best of 3: 28.8 ms per loop

Intel mkl BLAS 8 , np.correlate, , .

@Jamie:

%timeit b[0]*arr[:-1] + b[1]*arr[1:]
100 loops, best of 3: 8.43 ms per loop

np.convolve(a,b[::-1],mode=valid) correlate.

+3

, :

shifted_array=numpy.append(original_array[1:],0)
result_array=x*original_array+y*shifted_array

, , for.

, ( ):

result_array=[x*original_array[i]+y*original_array[i+1] for i in xrange(len(original_array)-1)]

, python, , -.

2000 . , , , MemoryError ( ).

, , , ( 1-2 ) , .

, [[a,b],[b,c],[c,d],[d,e],...], , , for ( ), , .

+1

a = np.array([a,b,c,d,e,...]), b = np.array([x, y, ...]), numpy:

a = np.arange(8) 
b = np.array([1, 2])

a = a.repeat(2)[1:-1]
ans = a.reshape(-1, b.shape[0]).dot(b)

( ):

@Ophion solution:
# 100000 loops, best of 3: 4.67 µs per loop

This solution:
# 100000 loops, best of 3: 9.78 µs per loop

So he is slower. @Jaime's solution is better since it does not copy data like this.

0
source

All Articles