To compute a 7-day moving average:
J:
7 (+/%#)\ i.999
BQN:
(+´÷≠)˘7↕↕9
Python:
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
np.average(sliding_window_view(np.arange(0,1000,dtype=np.float64),7),axis=1)
Apple:
[((+)/x)%ℝ(:x)]\`7 (𝒻 0 999 1000)
Performance
(10000000) 6!:2 '7 (+/%#) \ i.999'
1.82554e_6
)time:100000 (+´÷≠)˘7↕↕999
29.9us
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
%timeit np.average(sliding_window_view(np.arange(0,1000,dtype=np.float64),7),axis=1)
59.6 µs ± 366 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
> :bench [((+)/x)%ℝ(:x)]\`7 (𝒻 0 999 1000)
benchmarking...
time 8.849 μs (8.813 μs .. 8.875 μs)
1.000 R² (1.000 R² .. 1.000 R²)
mean 8.795 μs (8.768 μs .. 8.826 μs)
std dev 96.22 ns (82.58 ns .. 120.6 ns)
I suspect Python is slower because it allocates the entire intermediate array. In J (and Apple), we have an adverb which applies a verb to infixes directly; adroit choice of primitives make an array programming style feasible.