Skip to content

Commit 6641c83

Browse files
committed
Merge pull request #5760 from yieldsfalsehood/master
Update rolling skew & kurtosis to handle cases where they aren't defined
2 parents 9e21718 + b123ece commit 6641c83

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

doc/source/release.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ Bug Fixes
111111
- Bug in ``pd.read_msgpack`` with inferring a ``DateTimeIndex`` frequencey
112112
incorrectly (:issue:`5947`)
113113
- Fixed ``to_datetime`` for array with both Tz-aware datetimes and ``NaT``s (:issue:`5961`)
114+
- Bug in rolling skew/kurtosis when passed a Series with bad data (:issue:`5749`)
114115
115116
pandas 0.13.0
116117
-------------

pandas/algos.pyx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,8 +1167,11 @@ def roll_skew(ndarray[double_t] input, int win, int minp):
11671167

11681168
R = sqrt(B)
11691169

1170-
output[i] = ((sqrt(nobs * (nobs - 1.)) * C) /
1171-
((nobs-2) * R * R * R))
1170+
if B == 0 or nobs < 3:
1171+
output[i] = NaN
1172+
else:
1173+
output[i] = ((sqrt(nobs * (nobs - 1.)) * C) /
1174+
((nobs-2) * R * R * R))
11721175
else:
11731176
output[i] = NaN
11741177

@@ -1236,10 +1239,15 @@ def roll_kurt(ndarray[double_t] input,
12361239
R = R * A
12371240
D = xxxx / nobs - R - 6*B*A*A - 4*C*A
12381241

1239-
K = (nobs * nobs - 1.)*D/(B*B) - 3*((nobs-1.)**2)
1240-
K = K / ((nobs - 2.)*(nobs-3.))
1242+
if B == 0 or nobs < 4:
1243+
output[i] = NaN
1244+
1245+
else:
1246+
K = (nobs * nobs - 1.)*D/(B*B) - 3*((nobs-1.)**2)
1247+
K = K / ((nobs - 2.)*(nobs-3.))
1248+
1249+
output[i] = K
12411250

1242-
output[i] = K
12431251
else:
12441252
output[i] = NaN
12451253

pandas/stats/tests/test_moments.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,50 @@ def test_expanding_corr_pairwise(self):
741741
for i in result.items:
742742
assert_almost_equal(result[i], rolling_result[i])
743743

744+
def test_rolling_skew_edge_cases(self):
745+
746+
all_nan = Series([np.NaN] * 5)
747+
748+
# yields all NaN (0 variance)
749+
d = Series([1] * 5)
750+
x = mom.rolling_skew(d, window=5)
751+
assert_series_equal(all_nan, x)
752+
753+
# yields all NaN (window too small)
754+
d = Series(np.random.randn(5))
755+
x = mom.rolling_skew(d, window=2)
756+
assert_series_equal(all_nan, x)
757+
758+
# yields [NaN, NaN, NaN, 0.177994, 1.548824]
759+
d = Series([-1.50837035, -0.1297039 , 0.19501095,
760+
1.73508164, 0.41941401])
761+
expected = Series([np.NaN, np.NaN, np.NaN,
762+
0.177994, 1.548824])
763+
x = mom.rolling_skew(d, window=4)
764+
assert_series_equal(expected, x)
765+
766+
def test_rolling_kurt_edge_cases(self):
767+
768+
all_nan = Series([np.NaN] * 5)
769+
770+
# yields all NaN (0 variance)
771+
d = Series([1] * 5)
772+
x = mom.rolling_kurt(d, window=5)
773+
assert_series_equal(all_nan, x)
774+
775+
# yields all NaN (window too small)
776+
d = Series(np.random.randn(5))
777+
x = mom.rolling_kurt(d, window=3)
778+
assert_series_equal(all_nan, x)
779+
780+
# yields [NaN, NaN, NaN, 1.224307, 2.671499]
781+
d = Series([-1.50837035, -0.1297039 , 0.19501095,
782+
1.73508164, 0.41941401])
783+
expected = Series([np.NaN, np.NaN, np.NaN,
784+
1.224307, 2.671499])
785+
x = mom.rolling_kurt(d, window=4)
786+
assert_series_equal(expected, x)
787+
744788
def _check_expanding_ndarray(self, func, static_comp, has_min_periods=True,
745789
has_time_rule=True, preserve_nan=True):
746790
result = func(self.arr)

0 commit comments

Comments
 (0)