From 00244d0ea9d81016307a7a6b0d82de94dce34bcb Mon Sep 17 00:00:00 2001 From: sinhrks Date: Tue, 2 Aug 2016 08:03:51 +0900 Subject: [PATCH] BUG: Series creation with datetime64 with non-ns unit as object dtype --- doc/source/whatsnew/v0.19.0.txt | 2 ++ pandas/tests/series/test_constructors.py | 10 +++++++++- pandas/tests/test_algos.py | 7 ++++--- pandas/types/cast.py | 2 ++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v0.19.0.txt b/doc/source/whatsnew/v0.19.0.txt index 425b8daec6081..d069a25c58143 100644 --- a/doc/source/whatsnew/v0.19.0.txt +++ b/doc/source/whatsnew/v0.19.0.txt @@ -842,6 +842,8 @@ Bug Fixes - Bug in ``RangeIndex`` can be created without no arguments rather than raises ``TypeError`` (:issue:`13793`) - Bug in ``.value_counts`` raises ``OutOfBoundsDatetime`` if data exceeds ``datetime64[ns]`` bounds (:issue:`13663`) - Bug in ``DatetimeIndex`` may raise ``OutOfBoundsDatetime`` if input ``np.datetime64`` has other unit than ``ns`` (:issue:`9114`) +- Bug in ``Series`` creation with ``np.datetime64`` which has other unit than ``ns`` as ``object`` dtype results in incorrect values (:issue:`13876`) + - Bug in ``isnull`` ``notnull`` raise ``TypeError`` if input datetime-like has other unit than ``ns`` (:issue:`13389`) - Bug in ``.merge`` may raise ``TypeError`` if input datetime-like has other unit than ``ns`` (:issue:`13389`) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index c8e04f1ffd75f..ed7b0fda19cb7 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -381,13 +381,21 @@ def test_constructor_dtype_datetime64(self): # coerce datetime64 non-ns properly dates = date_range('01-Jan-2015', '01-Dec-2015', freq='M') values2 = dates.view(np.ndarray).astype('datetime64[ns]') - expected = Series(values2, dates) + expected = Series(values2, index=dates) for dtype in ['s', 'D', 'ms', 'us', 'ns']: values1 = dates.view(np.ndarray).astype('M8[{0}]'.format(dtype)) result = Series(values1, dates) assert_series_equal(result, expected) + # GH 13876 + # coerce to non-ns to object properly + expected = Series(values2, index=dates, dtype=object) + for dtype in ['s', 'D', 'ms', 'us', 'ns']: + values1 = dates.view(np.ndarray).astype('M8[{0}]'.format(dtype)) + result = Series(values1, index=dates, dtype=object) + assert_series_equal(result, expected) + # leave datetime.date alone dates2 = np.array([d.date() for d in dates.to_pydatetime()], dtype=object) diff --git a/pandas/tests/test_algos.py b/pandas/tests/test_algos.py index 9535a3f97955c..94c67ac7dd61a 100644 --- a/pandas/tests/test_algos.py +++ b/pandas/tests/test_algos.py @@ -777,7 +777,6 @@ def test_datetime_likes(self): exp_false = exp_first | exp_last for case in cases: - print(case) res_first = algos.duplicated(case, keep='first') tm.assert_numpy_array_equal(res_first, exp_first) @@ -788,7 +787,8 @@ def test_datetime_likes(self): tm.assert_numpy_array_equal(res_false, exp_false) # index - for idx in [pd.Index(case), pd.Index(case, dtype='category')]: + for idx in [pd.Index(case), pd.Index(case, dtype='category'), + pd.Index(case, dtype=object)]: res_first = idx.duplicated(keep='first') tm.assert_numpy_array_equal(res_first, exp_first) @@ -799,7 +799,8 @@ def test_datetime_likes(self): tm.assert_numpy_array_equal(res_false, exp_false) # series - for s in [pd.Series(case), pd.Series(case, dtype='category')]: + for s in [pd.Series(case), pd.Series(case, dtype='category'), + pd.Series(case, dtype=object)]: res_first = s.duplicated(keep='first') tm.assert_series_equal(res_first, pd.Series(exp_first)) diff --git a/pandas/types/cast.py b/pandas/types/cast.py index ca23d8d26a426..f4cb476672ec7 100644 --- a/pandas/types/cast.py +++ b/pandas/types/cast.py @@ -829,6 +829,8 @@ def _possibly_cast_to_datetime(value, dtype, errors='raise'): # coerce datetimelike to object elif is_datetime64_dtype(value) and not is_datetime64_dtype(dtype): if is_object_dtype(dtype): + if value.dtype != _NS_DTYPE: + value = value.astype(_NS_DTYPE) ints = np.asarray(value).view('i8') return tslib.ints_to_pydatetime(ints)