56
56
57
57
class _Window (PandasObject , SelectionMixin ):
58
58
_attributes = ['window' , 'min_periods' , 'freq' , 'center' , 'win_type' ,
59
- 'axis' , 'on' ]
59
+ 'axis' , 'on' , 'closed' ]
60
60
exclusions = set ()
61
61
62
62
def __init__ (self , obj , window = None , min_periods = None , freq = None ,
63
- center = False , win_type = None , axis = 0 , on = None , ** kwargs ):
63
+ center = False , win_type = None , axis = 0 , on = None , closed = 'right' ,
64
+ ** kwargs ):
64
65
65
66
if freq is not None :
66
67
warnings .warn ("The freq kw is deprecated and will be removed in a "
@@ -71,6 +72,7 @@ def __init__(self, obj, window=None, min_periods=None, freq=None,
71
72
self .blocks = []
72
73
self .obj = obj
73
74
self .on = on
75
+ self .closed = closed
74
76
self .window = window
75
77
self .min_periods = min_periods
76
78
self .freq = freq
@@ -101,6 +103,9 @@ def validate(self):
101
103
if self .min_periods is not None and not \
102
104
is_integer (self .min_periods ):
103
105
raise ValueError ("min_periods must be an integer" )
106
+ if self .closed not in ['right' , 'both' , 'left' , 'neither' ]:
107
+ raise ValueError ("closed must be 'right', 'left', 'both' or "
108
+ "'neither'" )
104
109
105
110
def _convert_freq (self , how = None ):
106
111
""" resample according to the how, return a new object """
@@ -374,8 +379,12 @@ class Window(_Window):
374
379
on : string, optional
375
380
For a DataFrame, column on which to calculate
376
381
the rolling window, rather than the index
382
+ closed : 'right', 'left', 'both', 'neither'
383
+ For offset-based windows, make the interval closed on the right, left,
384
+ or on both endpoints. Can also make the interval open on both endpoints
385
+ (neither).
377
386
378
- .. versionadded:: 0.19 .0
387
+ .. versionadded:: 0.20 .0
379
388
380
389
axis : int or string, default 0
381
390
@@ -717,12 +726,12 @@ def _apply(self, func, name=None, window=None, center=None,
717
726
raise ValueError ("we do not support this function "
718
727
"in _window.{0}" .format (func ))
719
728
720
- def func (arg , window , min_periods = None ):
729
+ def func (arg , window , min_periods = None , closed = None ):
721
730
minp = check_minp (min_periods , window )
722
731
# ensure we are only rolling on floats
723
732
arg = _ensure_float64 (arg )
724
733
return cfunc (arg ,
725
- window , minp , indexi , ** kwargs )
734
+ window , minp , indexi , closed , ** kwargs )
726
735
727
736
# calculation function
728
737
if center :
@@ -731,11 +740,13 @@ def func(arg, window, min_periods=None):
731
740
732
741
def calc (x ):
733
742
return func (np .concatenate ((x , additional_nans )),
734
- window , min_periods = self .min_periods )
743
+ window , min_periods = self .min_periods ,
744
+ closed = self .closed )
735
745
else :
736
746
737
747
def calc (x ):
738
- return func (x , window , min_periods = self .min_periods )
748
+ return func (x , window , min_periods = self .min_periods ,
749
+ closed = self .closed )
739
750
740
751
with np .errstate (all = 'ignore' ):
741
752
if values .ndim > 1 :
@@ -788,12 +799,13 @@ def apply(self, func, args=(), kwargs={}):
788
799
window = self ._get_window ()
789
800
offset = _offset (window , self .center )
790
801
index , indexi = self ._get_index ()
802
+ closed = self .closed
791
803
792
804
def f (arg , window , min_periods ):
793
805
minp = _use_window (min_periods , window )
794
806
return _window .roll_generic (arg , window , minp , indexi ,
795
807
offset , func , args ,
796
- kwargs )
808
+ kwargs , closed )
797
809
798
810
return self ._apply (f , func , args = args , kwargs = kwargs ,
799
811
center = False )
0 commit comments