36
36
37
37
38
38
class _Window (PandasObject , SelectionMixin ):
39
- _attributes = ['window' , 'min_periods' , 'freq ' , 'center ' , 'win_type ' ,
40
- 'axis' ]
39
+ _attributes = ['window' , 'min_periods' , 'min_weight ' , 'freq ' , 'center ' ,
40
+ 'win_type' , ' axis' ]
41
41
exclusions = set ()
42
42
43
- def __init__ (self , obj , window = None , min_periods = None , freq = None ,
44
- center = False , win_type = None , axis = 0 , ** kwargs ):
43
+ def __init__ (self , obj , window = None , min_periods = None , min_weight = None ,
44
+ freq = None , center = False , win_type = None , axis = 0 , ** kwargs ):
45
45
46
46
if freq is not None :
47
47
warnings .warn ("The freq kw is deprecated and will be removed in a "
@@ -52,6 +52,7 @@ def __init__(self, obj, window=None, min_periods=None, freq=None,
52
52
self .obj = obj
53
53
self .window = window
54
54
self .min_periods = min_periods
55
+ self .min_weight = min_weight
55
56
self .freq = freq
56
57
self .center = center
57
58
self .win_type = win_type
@@ -564,7 +565,12 @@ def calc(x):
564
565
565
566
results .append (result )
566
567
567
- return self ._wrap_results (results , blocks , obj )
568
+ result = self ._wrap_results (results , blocks , obj )
569
+
570
+ if self .min_weight :
571
+ result = result .where (_min_weight_mask (self , self .min_weight ))
572
+
573
+ return result
568
574
569
575
570
576
class _Rolling_and_Expanding (_Rolling ):
@@ -804,7 +810,7 @@ def _get_corr(a, b):
804
810
805
811
class Rolling (_Rolling_and_Expanding ):
806
812
"""
807
- Provides rolling window calculcations .
813
+ Provides rolling window calculations .
808
814
809
815
.. versionadded:: 0.18.0
810
816
@@ -981,14 +987,14 @@ class Expanding(_Rolling_and_Expanding):
981
987
of :meth:`~pandas.Series.resample` (i.e. using the `mean`).
982
988
"""
983
989
984
- _attributes = ['min_periods' , 'freq' , 'center' , 'axis' ]
990
+ _attributes = ['min_periods' , 'min_weight' , ' freq' , 'center' , 'axis' ]
985
991
986
- def __init__ (self , obj , min_periods = 1 , freq = None , center = False , axis = 0 ,
987
- ** kwargs ):
988
- return super (Expanding , self ).__init__ (obj = obj ,
989
- min_periods = min_periods ,
990
- freq = freq , center = center ,
991
- axis = axis )
992
+ def __init__ (self , obj , min_periods = 1 , min_weight = None , freq = None ,
993
+ center = False , axis = 0 , ** kwargs ):
994
+ super (Expanding , self ).__init__ (
995
+ obj = obj , min_periods = min_periods ,
996
+ min_weight = min_weight , freq = freq , center = center ,
997
+ axis = axis )
992
998
993
999
@property
994
1000
def _constructor (self ):
@@ -1204,14 +1210,16 @@ class EWM(_Rolling):
1204
1210
More details can be found at
1205
1211
http://pandas.pydata.org/pandas-docs/stable/computation.html#exponentially-weighted-windows
1206
1212
"""
1207
- _attributes = ['com' , 'min_periods' , 'freq' , 'adjust' , 'ignore_na' , 'axis' ]
1213
+ _attributes = ['com' , 'min_periods' , 'min_weight' , 'freq' , 'adjust' ,
1214
+ 'ignore_na' , 'axis' ]
1208
1215
1209
1216
def __init__ (self , obj , com = None , span = None , halflife = None , alpha = None ,
1210
- min_periods = 0 , freq = None , adjust = True , ignore_na = False ,
1211
- axis = 0 ):
1217
+ min_periods = 0 , min_weight = None , freq = None , adjust = True ,
1218
+ ignore_na = False , axis = 0 ):
1212
1219
self .obj = obj
1213
1220
self .com = _get_center_of_mass (com , span , halflife , alpha )
1214
1221
self .min_periods = min_periods
1222
+ self .min_weight = min_weight
1215
1223
self .freq = freq
1216
1224
self .adjust = adjust
1217
1225
self .ignore_na = ignore_na
@@ -1271,7 +1279,12 @@ def func(arg):
1271
1279
1272
1280
results .append (np .apply_along_axis (func , self .axis , values ))
1273
1281
1274
- return self ._wrap_results (results , blocks , obj )
1282
+ result = self ._wrap_results (results , blocks , obj )
1283
+
1284
+ if self .min_weight :
1285
+ result = result .where (_min_weight_mask (self , self .min_weight ))
1286
+
1287
+ return result
1275
1288
1276
1289
@Substitution (name = 'ewm' )
1277
1290
@Appender (_doc_template )
@@ -1477,6 +1490,19 @@ def _check_func(minp, window):
1477
1490
return _check_func
1478
1491
1479
1492
1493
+ def _min_weight_mask (rolling , min_weight ):
1494
+ data = rolling .obj
1495
+ valid_data = data .notnull ()
1496
+ # fill the object with 1s
1497
+ potential_valid = rolling .obj .copy ()
1498
+ potential_valid [:] = 1
1499
+
1500
+ valid_proportion = rolling ._shallow_copy (obj = valid_data , min_periods = 0 ,
1501
+ min_weight = None ).mean ()
1502
+
1503
+ return valid_proportion >= min_weight
1504
+
1505
+
1480
1506
def _use_window (minp , window ):
1481
1507
if minp is None :
1482
1508
return window
0 commit comments