Skip to content

Commit

Permalink
BUG: treat nobs=1 >= min_periods case in rolling_std/variance as 0 tr…
Browse files Browse the repository at this point in the history
…ivially. close #1884
  • Loading branch information
wesm committed Sep 13, 2012
1 parent 66a1637 commit 8743be5
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 3 deletions.
2 changes: 2 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ pandas 0.9.0
- Respect passed color keyword argument in Series.plot (#1890)
- Fix rolling_min/max when the window is larger than the size of the input
array. Check other malformed inputs (#1899, #1897)
- Rolling variance / standard deviation with only a single observation in
window (#1884)

pandas 0.8.1
============
Expand Down
7 changes: 6 additions & 1 deletion pandas/src/moments.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

def _check_minp(win, minp, N):
if minp > win:
raise ValueError('min_periods %d must be <= window %d'
raise ValueError('min_periods (%d) must be <= window (%d)'
% (minp, win))
elif minp > N:
minp = N + 1
Expand Down Expand Up @@ -382,6 +382,11 @@ def roll_var(ndarray[double_t] input, int win, int minp, int ddof=1):
sum_xx += val * val

if nobs >= minp:
# pathological case
if nobs == 1:
output[i] = 0
continue

output[i] = (nobs * sum_xx - sum_x * sum_x) / (nobs * (nobs - ddof))
else:
output[i] = NaN
Expand Down
4 changes: 2 additions & 2 deletions pandas/stats/moments.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,9 @@ def call_cython(arg, window, minp, **kwds):

_ts_std = lambda *a, **kw: _zsqrt(lib.roll_var(*a, **kw))
rolling_std = _rolling_func(_ts_std, 'Unbiased moving standard deviation',
check_minp=_require_min_periods(2))
check_minp=_require_min_periods(1))
rolling_var = _rolling_func(lib.roll_var, 'Unbiased moving variance',
check_minp=_require_min_periods(2))
check_minp=_require_min_periods(1))
rolling_skew = _rolling_func(lib.roll_skew, 'Unbiased moving skewness',
check_minp=_require_min_periods(3))
rolling_kurt = _rolling_func(lib.roll_kurt, 'Unbiased moving kurtosis',
Expand Down
11 changes: 11 additions & 0 deletions pandas/stats/tests/test_moments.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ def test_rolling_std(self):
self._check_moment_func(functools.partial(mom.rolling_std, ddof=0),
lambda x: np.std(x, ddof=0))

def test_rolling_std_1obs(self):
result = mom.rolling_std(np.array([1.,2.,3.,4.,5.]),
1, min_periods=1)
expected = np.zeros(5)

assert_almost_equal(result, expected)

result = mom.rolling_std(np.array([np.nan,np.nan,3.,4.,5.]),
3, min_periods=2)
self.assert_(np.isnan(result[2]))

def test_rolling_std_neg_sqrt(self):
# unit test from Bottleneck

Expand Down

0 comments on commit 8743be5

Please sign in to comment.