How to try a numpy array and efficiently perform calculations on each sample?

Suppose I have a 1d array, I want each element to be divided into the first element using a moving window and inside the window.

For example, if I have [2, 5, 8, 9, 6]a window size of 3, the result will be

[[1, 2.5, 4],
 [1, 1.6, 1.8],
 [1, 1.125, 0.75]].

What I'm doing now is basically a loop cycle

import numpy as np
arr = np.array([2., 5., 8., 9., 6.])
window_size = 3
for i in range(len(arr) - window_size + 1):
  result.append(arr[i : i + window_size] / arr[i])

and etc.

When the array is large, it is rather slow, I wonder if there are better ways? I think there is no complexity around O (n ^ 2) complexity, but maybe numpy has some optimizations that I don't know about.

+4
source share
1 answer

broadcasting -

N = 3  # Window size
nrows = a.size-N+1
a2D = a[np.arange(nrows)[:,None] + np.arange(N)]
out = a2D/a[:nrows,None].astype(float)

NumPy strides , :

n = a.strides[0]
a2D = np.lib.stride_tricks.as_strided(a,shape=(nrows,N),strides=(n,n))

-

In [73]: a
Out[73]: array([4, 9, 3, 6, 5, 7, 2])

In [74]: N = 3
    ...: nrows = a.size-N+1
    ...: a2D = a[np.arange(nrows)[:,None] + np.arange(N)]
    ...: out = a2D/a[:nrows,None].astype(float)
    ...: 

In [75]: out
Out[75]: 
array([[ 1.        ,  2.25      ,  0.75      ],
       [ 1.        ,  0.33333333,  0.66666667],
       [ 1.        ,  2.        ,  1.66666667],
       [ 1.        ,  0.83333333,  1.16666667],
       [ 1.        ,  1.4       ,  0.4       ]])
+5

Source: https://habr.com/ru/post/1658398/


All Articles