@@ -1705,6 +1705,74 @@ def roll_generic(ndarray[float64_t, cast=True] input, int win,
1705
1705
return output
1706
1706
1707
1707
1708
+ def roll_window (ndarray[float64_t , ndim = 1 , cast = True ] input ,
1709
+ ndarray[float64_t , ndim = 1 , cast = True ] weights,
1710
+ int minp , bint avg = True , bint avg_wgt = False ):
1711
+ """
1712
+ Assume len(weights) << len(input)
1713
+ """
1714
+ cdef:
1715
+ ndarray[double_t] output, tot_wgt
1716
+ ndarray[int64_t] counts
1717
+ Py_ssize_t in_i, win_i, win_n, win_k, in_n, in_k
1718
+ float64_t val_in, val_win, c, w
1719
+
1720
+ in_n = len (input )
1721
+ win_n = len (weights)
1722
+ output = np.zeros(in_n, dtype = float )
1723
+ counts = np.zeros(in_n, dtype = int )
1724
+ if avg:
1725
+ tot_wgt = np.zeros(in_n, dtype = float )
1726
+
1727
+ minp = _check_minp(len (weights), minp, in_n)
1728
+
1729
+ if avg_wgt:
1730
+ for win_i from 0 <= win_i < win_n:
1731
+ val_win = weights[win_i]
1732
+ if val_win != val_win:
1733
+ continue
1734
+
1735
+ for in_i from 0 <= in_i < in_n - (win_n - win_i) + 1 :
1736
+ val_in = input [in_i]
1737
+ if val_in == val_in:
1738
+ output[in_i + (win_n - win_i) - 1 ] += val_in * val_win
1739
+ counts[in_i + (win_n - win_i) - 1 ] += 1
1740
+ tot_wgt[in_i + (win_n - win_i) - 1 ] += val_win
1741
+
1742
+ for in_i from 0 <= in_i < in_n:
1743
+ c = counts[in_i]
1744
+ if c < minp:
1745
+ output[in_i] = NaN
1746
+ else :
1747
+ w = tot_wgt[in_i]
1748
+ if w == 0 :
1749
+ output[in_i] = NaN
1750
+ else :
1751
+ output[in_i] /= tot_wgt[in_i]
1752
+
1753
+ else :
1754
+ for win_i from 0 <= win_i < win_n:
1755
+ val_win = weights[win_i]
1756
+ if val_win != val_win:
1757
+ continue
1758
+
1759
+ for in_i from 0 <= in_i < in_n - (win_n - win_i) + 1 :
1760
+ val_in = input [in_i]
1761
+
1762
+ if val_in == val_in:
1763
+ output[in_i + (win_n - win_i) - 1 ] += val_in * val_win
1764
+ counts[in_i + (win_n - win_i) - 1 ] += 1
1765
+
1766
+ for in_i from 0 <= in_i < in_n:
1767
+ c = counts[in_i]
1768
+ if c < minp:
1769
+ output[in_i] = NaN
1770
+ elif avg:
1771
+ output[in_i] /= c
1772
+
1773
+ return output
1774
+
1775
+
1708
1776
# ----------------------------------------------------------------------
1709
1777
# group operations
1710
1778
0 commit comments