@@ -14,7 +14,7 @@ def calculate_variable_window_bounds(
1414 int64_t num_values ,
1515 int64_t window_size ,
1616 object min_periods , # unused but here to match get_window_bounds signature
17- object center , # unused but here to match get_window_bounds signature
17+ bint center ,
1818 object closed ,
1919 const int64_t[:] index
2020):
@@ -32,8 +32,8 @@ def calculate_variable_window_bounds(
3232 min_periods : object
3333 ignored, exists for compatibility
3434
35- center : object
36- ignored, exists for compatibility
35+ center : bint
36+ center the rolling window on the current observation
3737
3838 closed : str
3939 string of side of the window that should be closed
@@ -46,7 +46,8 @@ def calculate_variable_window_bounds(
4646 (ndarray[int64], ndarray[int64])
4747 """
4848 cdef:
49- bint left_closed = False , right_closed = False
49+ bint left_closed = False
50+ bint right_closed = False
5051 ndarray[int64_t, ndim= 1 ] start, end
5152 int64_t start_bound, end_bound, index_growth_sign = 1
5253 Py_ssize_t i, j
@@ -77,14 +78,27 @@ def calculate_variable_window_bounds(
7778 # right endpoint is open
7879 else :
7980 end[0 ] = 0
81+ if center:
82+ for j in range (0 , num_values + 1 ):
83+ if (index[j] == index[0 ] + index_growth_sign * window_size / 2 and
84+ right_closed):
85+ end[0 ] = j + 1
86+ break
87+ elif index[j] >= index[0 ] + index_growth_sign * window_size / 2 :
88+ end[0 ] = j
89+ break
8090
8191 with nogil:
8292
8393 # start is start of slice interval (including)
8494 # end is end of slice interval (not including)
8595 for i in range (1 , num_values):
86- end_bound = index[i]
87- start_bound = index[i] - index_growth_sign * window_size
96+ if center:
97+ end_bound = index[i] + index_growth_sign * window_size / 2
98+ start_bound = index[i] - index_growth_sign * window_size / 2
99+ else :
100+ end_bound = index[i]
101+ start_bound = index[i] - index_growth_sign * window_size
88102
89103 # left endpoint is closed
90104 if left_closed:
@@ -98,14 +112,27 @@ def calculate_variable_window_bounds(
98112 start[i] = j
99113 break
100114
115+ # for centered window advance the end bound until we are
116+ # outside the constraint
117+ if center:
118+ for j in range (end[i - 1 ], num_values + 1 ):
119+ if j == num_values:
120+ end[i] = j
121+ elif ((index[j] - end_bound) * index_growth_sign == 0 and
122+ right_closed):
123+ end[i] = j + 1
124+ break
125+ elif (index[j] - end_bound) * index_growth_sign >= 0 :
126+ end[i] = j
127+ break
101128 # end bound is previous end
102129 # or current index
103- if (index[end[i - 1 ]] - end_bound) * index_growth_sign <= 0 :
130+ elif (index[end[i - 1 ]] - end_bound) * index_growth_sign <= 0 :
104131 end[i] = i + 1
105132 else :
106133 end[i] = end[i - 1 ]
107134
108135 # right endpoint is open
109- if not right_closed:
136+ if not right_closed and not center :
110137 end[i] -= 1
111138 return start, end
0 commit comments