9
9
from numpy import NaN
10
10
import numpy as np
11
11
12
- from pandas .core .api import DataFrame , Series , notnull
12
+ from pandas .core .api import DataFrame , Series , notnull , Panel
13
13
import pandas .lib as lib
14
14
15
15
from pandas .util .decorators import Substitution , Appender
124
124
"""
125
125
126
126
127
- def rolling_count (arg , window , freq = None , time_rule = None ):
127
+ def rolling_count (arg , window , freq = None , center = False , time_rule = None ):
128
128
"""
129
129
Rolling count of number of non-NaN observations inside provided window.
130
130
@@ -134,6 +134,8 @@ def rolling_count(arg, window, freq=None, time_rule=None):
134
134
window : Number of observations used for calculating statistic
135
135
freq : None or string alias / date offset object, default=None
136
136
Frequency to conform to before computing statistic
137
+ center : boolean, default False
138
+ Whether the label should correspond with center of window
137
139
138
140
Returns
139
141
-------
@@ -146,7 +148,7 @@ def rolling_count(arg, window, freq=None, time_rule=None):
146
148
147
149
converted = np .isfinite (values ).astype (float )
148
150
result = rolling_sum (converted , window , min_periods = 1 ,
149
- time_rule = time_rule )
151
+ center = center ) # already converted
150
152
151
153
# putmask here?
152
154
result [np .isnan (result )] = 0
@@ -156,22 +158,37 @@ def rolling_count(arg, window, freq=None, time_rule=None):
156
158
157
159
@Substitution ("Unbiased moving covariance" , _binary_arg_flex , _flex_retval )
158
160
@Appender (_doc_template )
159
- def rolling_cov (arg1 , arg2 , window , min_periods = None , time_rule = None ):
161
+ def rolling_cov (arg1 , arg2 , window , min_periods = None , freq = None ,
162
+ center = False , time_rule = None ):
163
+ arg1 = _conv_timerule (arg1 , freq , time_rule )
164
+ arg2 = _conv_timerule (arg2 , freq , time_rule )
165
+ window = min (window , len (arg1 ), len (arg2 ))
160
166
def _get_cov (X , Y ):
161
- mean = lambda x : rolling_mean (x , window , min_periods , time_rule )
162
- count = rolling_count (X + Y , window , time_rule )
167
+ mean = lambda x : rolling_mean (x , window , min_periods )
168
+ count = rolling_count (X + Y , window )
163
169
bias_adj = count / (count - 1 )
164
170
return (mean (X * Y ) - mean (X ) * mean (Y )) * bias_adj
165
- return _flex_binary_moment (arg1 , arg2 , _get_cov )
166
-
171
+ rs = _flex_binary_moment (arg1 , arg2 , _get_cov )
172
+ if center :
173
+ if isinstance (rs , (Series , DataFrame , Panel )):
174
+ rs = rs .shift (- int ((window + 1 ) / 2. ))
175
+ else :
176
+ offset = int ((window + 1 ) / 2. )
177
+ rs [:- offset ] = rs [offset :]
178
+ rs [- offset :] = np .nan
179
+ return rs
167
180
168
181
@Substitution ("Moving sample correlation" , _binary_arg_flex , _flex_retval )
169
182
@Appender (_doc_template )
170
- def rolling_corr (arg1 , arg2 , window , min_periods = None , time_rule = None ):
183
+ def rolling_corr (arg1 , arg2 , window , min_periods = None , freq = None ,
184
+ center = False , time_rule = None ):
171
185
def _get_corr (a , b ):
172
- num = rolling_cov (a , b , window , min_periods , time_rule )
173
- den = (rolling_std (a , window , min_periods , time_rule ) *
174
- rolling_std (b , window , min_periods , time_rule ))
186
+ num = rolling_cov (a , b , window , min_periods , freq = freq ,
187
+ center = center , time_rule = time_rule )
188
+ den = (rolling_std (a , window , min_periods , freq = freq ,
189
+ center = center , time_rule = time_rule ) *
190
+ rolling_std (b , window , min_periods , freq = freq ,
191
+ center = center , time_rule = time_rule ))
175
192
return num / den
176
193
return _flex_binary_moment (arg1 , arg2 , _get_corr )
177
194
@@ -234,7 +251,7 @@ def rolling_corr_pairwise(df, window, min_periods=None):
234
251
235
252
236
253
def _rolling_moment (arg , window , func , minp , axis = 0 , freq = None ,
237
- time_rule = None , ** kwargs ):
254
+ center = False , time_rule = None , ** kwargs ):
238
255
"""
239
256
Rolling statistical measure using supplied function. Designed to be
240
257
used with passed-in Cython array-based functions.
@@ -249,6 +266,8 @@ def _rolling_moment(arg, window, func, minp, axis=0, freq=None,
249
266
axis : int, default 0
250
267
freq : None or string alias / date offset object, default=None
251
268
Frequency to conform to before computing statistic
269
+ center : boolean, default False
270
+ Whether the label should correspond with center of window
252
271
253
272
Returns
254
273
-------
@@ -260,8 +279,16 @@ def _rolling_moment(arg, window, func, minp, axis=0, freq=None,
260
279
# actually calculate the moment. Faster way to do this?
261
280
result = np .apply_along_axis (calc , axis , values )
262
281
263
- return return_hook (result )
282
+ rs = return_hook (result )
283
+ if center :
284
+ if isinstance (rs , (Series , DataFrame , Panel )):
285
+ rs = rs .shift (- int ((window + 1 ) / 2. ), axis = axis )
286
+ else :
287
+ offset = int ((window + 1 )/ 2. )
288
+ rs [:- offset ] = rs [offset :]
289
+ rs [- offset :] = np .nan
264
290
291
+ return rs
265
292
266
293
def _process_data_structure (arg , kill_inf = True ):
267
294
if isinstance (arg , DataFrame ):
@@ -450,12 +477,14 @@ def _rolling_func(func, desc, check_minp=_use_window):
450
477
@Substitution (desc , _unary_arg , _type_of_input )
451
478
@Appender (_doc_template )
452
479
@wraps (func )
453
- def f (arg , window , min_periods = None , freq = None , time_rule = None , ** kwargs ):
480
+ def f (arg , window , min_periods = None , freq = None , center = False ,
481
+ time_rule = None , ** kwargs ):
454
482
def call_cython (arg , window , minp , ** kwds ):
455
483
minp = check_minp (minp , window )
456
484
return func (arg , window , minp , ** kwds )
457
485
return _rolling_moment (arg , window , call_cython , min_periods ,
458
- freq = freq , time_rule = time_rule , ** kwargs )
486
+ freq = freq , center = center ,
487
+ time_rule = time_rule , ** kwargs )
459
488
460
489
return f
461
490
@@ -477,7 +506,7 @@ def call_cython(arg, window, minp, **kwds):
477
506
478
507
479
508
def rolling_quantile (arg , window , quantile , min_periods = None , freq = None ,
480
- time_rule = None ):
509
+ center = False , time_rule = None ):
481
510
"""Moving quantile
482
511
483
512
Parameters
@@ -489,6 +518,8 @@ def rolling_quantile(arg, window, quantile, min_periods=None, freq=None,
489
518
Minimum number of observations in window required to have a value
490
519
freq : None or string alias / date offset object, default=None
491
520
Frequency to conform to before computing statistic
521
+ center : boolean, default False
522
+ Whether the label should correspond with center of window
492
523
493
524
Returns
494
525
-------
@@ -499,11 +530,11 @@ def call_cython(arg, window, minp):
499
530
minp = _use_window (minp , window )
500
531
return lib .roll_quantile (arg , window , minp , quantile )
501
532
return _rolling_moment (arg , window , call_cython , min_periods ,
502
- freq = freq , time_rule = time_rule )
533
+ freq = freq , center = center , time_rule = time_rule )
503
534
504
535
505
536
def rolling_apply (arg , window , func , min_periods = None , freq = None ,
506
- time_rule = None ):
537
+ center = False , time_rule = None ):
507
538
"""Generic moving function application
508
539
509
540
Parameters
@@ -516,6 +547,8 @@ def rolling_apply(arg, window, func, min_periods=None, freq=None,
516
547
Minimum number of observations in window required to have a value
517
548
freq : None or string alias / date offset object, default=None
518
549
Frequency to conform to before computing statistic
550
+ center : boolean, default False
551
+ Whether the label should correspond with center of window
519
552
520
553
Returns
521
554
-------
@@ -525,21 +558,23 @@ def call_cython(arg, window, minp):
525
558
minp = _use_window (minp , window )
526
559
return lib .roll_generic (arg , window , minp , func )
527
560
return _rolling_moment (arg , window , call_cython , min_periods ,
528
- freq = freq , time_rule = time_rule )
561
+ freq = freq , center = center , time_rule = time_rule )
529
562
530
563
531
564
def _expanding_func (func , desc , check_minp = _use_window ):
532
565
@Substitution (desc , _unary_arg , _type_of_input )
533
566
@Appender (_expanding_doc )
534
567
@wraps (func )
535
- def f (arg , min_periods = 1 , freq = None , time_rule = None , ** kwargs ):
568
+ def f (arg , min_periods = 1 , freq = None , center = False , time_rule = None ,
569
+ ** kwargs ):
536
570
window = len (arg )
537
571
538
572
def call_cython (arg , window , minp , ** kwds ):
539
573
minp = check_minp (minp , window )
540
574
return func (arg , window , minp , ** kwds )
541
575
return _rolling_moment (arg , window , call_cython , min_periods ,
542
- freq = freq , time_rule = time_rule , ** kwargs )
576
+ freq = freq , center = center ,
577
+ time_rule = time_rule , ** kwargs )
543
578
544
579
return f
545
580
@@ -560,7 +595,7 @@ def call_cython(arg, window, minp, **kwds):
560
595
check_minp = _require_min_periods (4 ))
561
596
562
597
563
- def expanding_count (arg , freq = None , time_rule = None ):
598
+ def expanding_count (arg , freq = None , center = False , time_rule = None ):
564
599
"""
565
600
Expanding count of number of non-NaN observations.
566
601
@@ -569,16 +604,19 @@ def expanding_count(arg, freq=None, time_rule=None):
569
604
arg : DataFrame or numpy ndarray-like
570
605
freq : None or string alias / date offset object, default=None
571
606
Frequency to conform to before computing statistic
607
+ center : boolean, default False
608
+ Whether the label should correspond with center of window
572
609
573
610
Returns
574
611
-------
575
612
expanding_count : type of caller
576
613
"""
577
- return rolling_count (arg , len (arg ), freq = freq , time_rule = time_rule )
614
+ return rolling_count (arg , len (arg ), freq = freq , center = center ,
615
+ time_rule = time_rule )
578
616
579
617
580
618
def expanding_quantile (arg , quantile , min_periods = 1 , freq = None ,
581
- time_rule = None ):
619
+ center = False , time_rule = None ):
582
620
"""Expanding quantile
583
621
584
622
Parameters
@@ -589,29 +627,35 @@ def expanding_quantile(arg, quantile, min_periods=1, freq=None,
589
627
Minimum number of observations in window required to have a value
590
628
freq : None or string alias / date offset object, default=None
591
629
Frequency to conform to before computing statistic
630
+ center : boolean, default False
631
+ Whether the label should correspond with center of window
592
632
593
633
Returns
594
634
-------
595
635
y : type of input argument
596
636
"""
597
637
return rolling_quantile (arg , len (arg ), quantile , min_periods = min_periods ,
598
- freq = freq , time_rule = time_rule )
638
+ freq = freq , center = center , time_rule = time_rule )
599
639
600
640
601
641
@Substitution ("Unbiased expanding covariance" , _binary_arg_flex , _flex_retval )
602
642
@Appender (_expanding_doc )
603
- def expanding_cov (arg1 , arg2 , min_periods = 1 , time_rule = None ):
643
+ def expanding_cov (arg1 , arg2 , min_periods = 1 , freq = None , center = False ,
644
+ time_rule = None ):
604
645
window = max (len (arg1 ), len (arg2 ))
605
646
return rolling_cov (arg1 , arg2 , window ,
606
- min_periods = min_periods , time_rule = time_rule )
647
+ min_periods = min_periods , freq = freq ,
648
+ center = center , time_rule = time_rule )
607
649
608
650
609
651
@Substitution ("Expanding sample correlation" , _binary_arg_flex , _flex_retval )
610
652
@Appender (_expanding_doc )
611
- def expanding_corr (arg1 , arg2 , min_periods = 1 , time_rule = None ):
653
+ def expanding_corr (arg1 , arg2 , min_periods = 1 , freq = None , center = False ,
654
+ time_rule = None ):
612
655
window = max (len (arg1 ), len (arg2 ))
613
656
return rolling_corr (arg1 , arg2 , window ,
614
- min_periods = min_periods , time_rule = time_rule )
657
+ min_periods = min_periods ,
658
+ freq = freq , center = center , time_rule = time_rule )
615
659
616
660
617
661
def expanding_corr_pairwise (df , min_periods = 1 ):
@@ -634,7 +678,8 @@ def expanding_corr_pairwise(df, min_periods=1):
634
678
return rolling_corr_pairwise (df , window , min_periods = min_periods )
635
679
636
680
637
- def expanding_apply (arg , func , min_periods = 1 , freq = None , time_rule = None ):
681
+ def expanding_apply (arg , func , min_periods = 1 , freq = None , center = False ,
682
+ time_rule = None ):
638
683
"""Generic expanding function application
639
684
640
685
Parameters
@@ -646,11 +691,13 @@ def expanding_apply(arg, func, min_periods=1, freq=None, time_rule=None):
646
691
Minimum number of observations in window required to have a value
647
692
freq : None or string alias / date offset object, default=None
648
693
Frequency to conform to before computing statistic
694
+ center : boolean, default False
695
+ Whether the label should correspond with center of window
649
696
650
697
Returns
651
698
-------
652
699
y : type of input argument
653
700
"""
654
701
window = len (arg )
655
702
return rolling_apply (arg , window , func , min_periods = min_periods , freq = freq ,
656
- time_rule = time_rule )
703
+ center = center , time_rule = time_rule )
0 commit comments