diff --git a/doc/source/release.rst b/doc/source/release.rst index b2c1e585fd90f..7afe53cf33904 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -279,6 +279,7 @@ pandas 0.11.1 - Fix index name not propogating when using ``shift`` - Fixed dropna=False being ignored with multi-index stack (:issue:`3997`) - Fixed flattening of columns when renaming MultiIndex columns DataFrame (:issue:`4004`) + - Fix ``Series.clip`` for datetime series. NA/NaN threshold values will now throw ValueError (:issue:`3996`) .. _Gh3616: https://github.com/pydata/pandas/issues/3616 diff --git a/pandas/core/series.py b/pandas/core/series.py index 938cd99dcef8d..47ae56f6ca2fd 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1984,7 +1984,10 @@ def clip_upper(self, threshold): ------- clipped : Series """ - return pa.where(self > threshold, threshold, self) + if isnull(threshold): + raise ValueError("Cannot use an NA value as a clip threshold") + + return self.where((self <= threshold) | isnull(self), threshold) def clip_lower(self, threshold): """ @@ -1998,7 +2001,10 @@ def clip_lower(self, threshold): ------- clipped : Series """ - return pa.where(self < threshold, threshold, self) + if isnull(threshold): + raise ValueError("Cannot use an NA value as a clip threshold") + + return self.where((self >= threshold) | isnull(self), threshold) def dot(self, other): """ diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index cf7d360b5a93d..05b5876f6fc86 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -2840,6 +2840,21 @@ def test_clip(self): assert_series_equal(result, expected) self.assert_(isinstance(expected, Series)) + def test_clip_types_and_nulls(self): + + sers = [Series([np.nan, 1.0, 2.0, 3.0]), + Series([None, 'a', 'b', 'c']), + Series(pd.to_datetime([np.nan, 1, 2, 3], unit='D'))] + + for s in sers: + thresh = s[2] + l = s.clip_lower(thresh) + u = s.clip_upper(thresh) + self.assertEqual(l[notnull(l)].min(), thresh) + self.assertEqual(u[notnull(u)].max(), thresh) + self.assertEqual(list(isnull(s)), list(isnull(l))) + self.assertEqual(list(isnull(s)), list(isnull(u))) + def test_valid(self): ts = self.ts.copy() ts[::2] = np.NaN