@@ -263,11 +263,47 @@ def __init__(
263
263
def __iter__ (self ):
264
264
if len (self .dim ) > 1 :
265
265
raise ValueError ("__iter__ is only supported for 1d-rolling" )
266
- stops = np .arange (1 , len (self .window_labels ) + 1 )
267
- starts = stops - int (self .window [0 ])
268
- starts [: int (self .window [0 ])] = 0
269
- for (label , start , stop ) in zip (self .window_labels , starts , stops ):
270
- window = self .obj .isel (** {self .dim [0 ]: slice (start , stop )})
266
+ dim = self .dim [0 ]
267
+ center = self .center [0 ]
268
+ pad = self .pad [0 ]
269
+ window = self .window [0 ]
270
+ center_offset = window // 2 if center else 0
271
+
272
+ pads = utils .get_pads (self .dim , self .window , self .center , self .pad )
273
+ start_pad , end_pad = pads [dim ]
274
+
275
+ # Select the proper subset of labels, based on whether or not to center and/or pad
276
+ first_label_idx = 0 if pad else center_offset if center else window - 1
277
+ last_label_idx = (
278
+ len (self .obj [dim ])
279
+ if pad or not center
280
+ else len (self .obj [dim ]) - center_offset
281
+ )
282
+
283
+ labels = (
284
+ self .obj [dim ][slice (first_label_idx , last_label_idx )]
285
+ if self .obj [dim ].coords
286
+ else np .arange (last_label_idx - first_label_idx )
287
+ )
288
+
289
+ padded_obj = self .obj .pad (pads , mode = "constant" , constant_values = dtypes .NA )
290
+
291
+ if pad and not center :
292
+ first_stop = 1
293
+ last_stop = len (self .obj [dim ])
294
+ elif pad and center :
295
+ first_stop = end_pad + 1
296
+ last_stop = len (self .obj [dim ]) + end_pad
297
+ elif not pad :
298
+ first_stop = window
299
+ last_stop = len (self .obj [dim ])
300
+
301
+ # These are indicies into the padded array, so we need to add start_pad
302
+ stops = np .arange (first_stop , last_stop + 1 ) + start_pad
303
+ starts = stops - window
304
+
305
+ for (label , start , stop ) in zip (labels , starts , stops ):
306
+ window = padded_obj .isel ({self .dim [0 ]: slice (start , stop )})
271
307
272
308
counts = window .count (dim = self .dim [0 ])
273
309
window = window .where (counts >= self .min_periods )
@@ -486,15 +522,17 @@ def _counts(self, keep_attrs):
486
522
# array is faster to be reduced than object array.
487
523
# The use of skipna==False is also faster since it does not need to
488
524
# copy the strided array.
525
+ output_dim_coords = self ._get_rolling_dim_coords ()
489
526
counts = (
490
527
self .obj .notnull (keep_attrs = keep_attrs )
491
528
.rolling (
492
529
center = {d : self .center [i ] for i , d in enumerate (self .dim )},
530
+ pad = {p : self .pad [i ] for i , p in enumerate (self .pad )},
493
531
** {d : w for d , w in zip (self .dim , self .window )},
494
532
)
495
533
.construct (rolling_dim , fill_value = False , keep_attrs = keep_attrs )
496
534
.sum (dim = list (rolling_dim .values ()), skipna = False , keep_attrs = keep_attrs )
497
- )
535
+ ). sel ( output_dim_coords )
498
536
return counts
499
537
500
538
def _bottleneck_reduce (self , func , keep_attrs , ** kwargs ):
0 commit comments