From 3e986f16c93a6c5be729bce0b5f8efc3c8beb30b Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Fri, 17 Nov 2017 20:03:56 -0800 Subject: [PATCH 1/5] centralize remaining uses of pandas_datetime_to_datetimestruct in conversion --- pandas/_libs/index.pyx | 2 +- pandas/_libs/tslib.pxd | 2 - pandas/_libs/tslib.pyx | 86 +------------------ pandas/_libs/tslibs/conversion.pxd | 2 + pandas/_libs/tslibs/conversion.pyx | 82 +++++++++++++++++- pandas/core/indexes/datetimes.py | 2 +- pandas/core/internals.py | 7 +- pandas/core/tools/datetimes.py | 4 +- .../indexes/datetimes/test_construction.py | 3 +- 9 files changed, 95 insertions(+), 95 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index d74673b17c8d9..ecb315bca2031 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -13,7 +13,7 @@ cimport util import numpy as np -from tslib cimport _to_i8 +from tslibs.conversion cimport _to_i8 from hashtable cimport HashTable diff --git a/pandas/_libs/tslib.pxd b/pandas/_libs/tslib.pxd index 1c2c679904868..c764f486c0b12 100644 --- a/pandas/_libs/tslib.pxd +++ b/pandas/_libs/tslib.pxd @@ -3,5 +3,3 @@ from numpy cimport ndarray, int64_t from tslibs.conversion cimport convert_to_tsobject cdef bint _check_all_nulls(obj) - -cdef _to_i8(object val) diff --git a/pandas/_libs/tslib.pyx b/pandas/_libs/tslib.pyx index 0777b83de4645..bd2bc98deda4f 100644 --- a/pandas/_libs/tslib.pyx +++ b/pandas/_libs/tslib.pyx @@ -36,7 +36,7 @@ from cpython.datetime cimport (PyDelta_Check, PyTZInfo_Check, # import datetime C API PyDateTime_IMPORT # this is our datetime.pxd -from datetime cimport pandas_datetime_to_datetimestruct, _string_to_dts +from datetime cimport _string_to_dts # stdlib datetime imports from datetime import time as datetime_time @@ -46,10 +46,9 @@ from tslibs.np_datetime cimport (check_dts_bounds, reverse_ops, cmp_scalar, pandas_datetimestruct, - PANDAS_DATETIMEUNIT, PANDAS_FR_ns, dt64_to_dtstruct, dtstruct_to_dt64, pydatetime_to_dt64, pydate_to_dt64, - get_datetime64_unit, get_datetime64_value, + get_datetime64_value, get_timedelta64_value, days_per_month_table, dayofweek, is_leapyear) @@ -1242,43 +1241,6 @@ cpdef inline object _localize_pydatetime(object dt, object tz): return dt.replace(tzinfo=tz) -def datetime_to_datetime64(ndarray[object] values): - cdef: - Py_ssize_t i, n = len(values) - object val, inferred_tz = None - ndarray[int64_t] iresult - pandas_datetimestruct dts - _TSObject _ts - - result = np.empty(n, dtype='M8[ns]') - iresult = result.view('i8') - for i in range(n): - val = values[i] - if _checknull_with_nat(val): - iresult[i] = NPY_NAT - elif PyDateTime_Check(val): - if val.tzinfo is not None: - if inferred_tz is not None: - if get_timezone(val.tzinfo) != inferred_tz: - raise ValueError('Array must be all same time zone') - else: - inferred_tz = get_timezone(val.tzinfo) - - _ts = convert_datetime_to_tsobject(val, None) - iresult[i] = _ts.value - check_dts_bounds(&_ts.dts) - else: - if inferred_tz is not None: - raise ValueError('Cannot mix tz-aware with ' - 'tz-naive values') - iresult[i] = pydatetime_to_dt64(val, &dts) - check_dts_bounds(&dts) - else: - raise TypeError('Unrecognized value type: %s' % type(val)) - - return result, inferred_tz - - def format_array_from_datetime(ndarray[int64_t] values, object tz=None, object format=None, object na_rep=None): """ @@ -1758,50 +1720,6 @@ cpdef array_to_datetime(ndarray[object] values, errors='raise', return oresult -# ---------------------------------------------------------------------- -# Conversion routines - -def cast_to_nanoseconds(ndarray arr): - cdef: - Py_ssize_t i, n = arr.size - ndarray[int64_t] ivalues, iresult - PANDAS_DATETIMEUNIT unit - pandas_datetimestruct dts - - shape = ( arr).shape - - ivalues = arr.view(np.int64).ravel() - - result = np.empty(shape, dtype='M8[ns]') - iresult = result.ravel().view(np.int64) - - if len(iresult) == 0: - return result - - unit = get_datetime64_unit(arr.flat[0]) - for i in range(n): - if ivalues[i] != NPY_NAT: - pandas_datetime_to_datetimestruct(ivalues[i], unit, &dts) - iresult[i] = dtstruct_to_dt64(&dts) - check_dts_bounds(&dts) - else: - iresult[i] = NPY_NAT - - return result - - -cdef inline _to_i8(object val): - cdef pandas_datetimestruct dts - try: - return val.value - except AttributeError: - if is_datetime64_object(val): - return get_datetime64_value(val) - elif PyDateTime_Check(val): - return Timestamp(val).value - return val - - # ---------------------------------------------------------------------- # Accessors diff --git a/pandas/_libs/tslibs/conversion.pxd b/pandas/_libs/tslibs/conversion.pxd index ad817ce8852f2..5b0faa02515dc 100644 --- a/pandas/_libs/tslibs/conversion.pxd +++ b/pandas/_libs/tslibs/conversion.pxd @@ -28,3 +28,5 @@ cpdef int64_t tz_convert_single(int64_t val, object tz1, object tz2) cdef int64_t get_datetime64_nanos(object val) except? -1 cpdef int64_t pydt_to_i8(object pydt) except? -1 + +cdef _to_i8(object val) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 2a55180b53498..868ec5d12f10d 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -40,7 +40,7 @@ from timezones cimport ( from parsing import parse_datetime_string from nattype import nat_strings, NaT -from nattype cimport NPY_NAT +from nattype cimport NPY_NAT, _checknull_with_nat # ---------------------------------------------------------------------- # Constants @@ -73,6 +73,86 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1: return ival + +def cast_to_nanoseconds(ndarray arr): + cdef: + Py_ssize_t i, n = arr.size + ndarray[int64_t] ivalues, iresult + PANDAS_DATETIMEUNIT unit + pandas_datetimestruct dts + + shape = ( arr).shape + + ivalues = arr.view(np.int64).ravel() + + result = np.empty(shape, dtype='M8[ns]') + iresult = result.ravel().view(np.int64) + + if len(iresult) == 0: + return result + + unit = get_datetime64_unit(arr.flat[0]) + for i in range(n): + if ivalues[i] != NPY_NAT: + pandas_datetime_to_datetimestruct(ivalues[i], unit, &dts) + iresult[i] = dtstruct_to_dt64(&dts) + check_dts_bounds(&dts) + else: + iresult[i] = NPY_NAT + + return result + + +def datetime_to_datetime64(ndarray[object] values): + cdef: + Py_ssize_t i, n = len(values) + object val, inferred_tz = None + ndarray[int64_t] iresult + pandas_datetimestruct dts + _TSObject _ts + + result = np.empty(n, dtype='M8[ns]') + iresult = result.view('i8') + for i in range(n): + val = values[i] + if _checknull_with_nat(val): + iresult[i] = NPY_NAT + elif PyDateTime_Check(val): + if val.tzinfo is not None: + if inferred_tz is not None: + if get_timezone(val.tzinfo) != inferred_tz: + raise ValueError('Array must be all same time zone') + else: + inferred_tz = get_timezone(val.tzinfo) + + _ts = convert_datetime_to_tsobject(val, None) + iresult[i] = _ts.value + check_dts_bounds(&_ts.dts) + else: + if inferred_tz is not None: + raise ValueError('Cannot mix tz-aware with ' + 'tz-naive values') + iresult[i] = pydatetime_to_dt64(val, &dts) + check_dts_bounds(&dts) + else: + raise TypeError('Unrecognized value type: %s' % type(val)) + + return result, inferred_tz + + +cdef inline _to_i8(object val): + cdef: + pandas_datetimestruct dts + try: + return val.value + except AttributeError: + if is_datetime64_object(val): + return get_datetime64_value(val) + elif PyDateTime_Check(val): + convert_datetime_to_tsobject(val, None).value + return val + + # ---------------------------------------------------------------------- # _TSObject Conversion diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index ba96979435f81..2c0ef318e7640 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -409,7 +409,7 @@ def __new__(cls, data=None, verify_integrity = False else: if data.dtype != _NS_DTYPE: - subarr = libts.cast_to_nanoseconds(data) + subarr = conversion.cast_to_nanoseconds(data) else: subarr = data else: diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 665f9ff8eb7a0..ae2499bbd7047 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -68,6 +68,7 @@ from pandas._libs import lib, tslib from pandas._libs.tslib import Timedelta from pandas._libs.lib import BlockPlacement +from pandas._libs.tslibs import conversion from pandas.util._decorators import cache_readonly from pandas.util._validators import validate_bool_kwarg @@ -2462,7 +2463,7 @@ class DatetimeBlock(DatetimeLikeBlockMixin, Block): def __init__(self, values, placement, fastpath=False, **kwargs): if values.dtype != _NS_DTYPE: - values = tslib.cast_to_nanoseconds(values) + values = conversion.cast_to_nanoseconds(values) super(DatetimeBlock, self).__init__(values, fastpath=True, placement=placement, **kwargs) @@ -2584,7 +2585,7 @@ def set(self, locs, values, check=False): """ if values.dtype != _NS_DTYPE: # Workaround for numpy 1.6 bug - values = tslib.cast_to_nanoseconds(values) + values = conversion.cast_to_nanoseconds(values) self.values[locs] = values @@ -4674,7 +4675,7 @@ def form_blocks(arrays, names, axes): complex_items.append((i, k, v)) elif issubclass(v.dtype.type, np.datetime64): if v.dtype != _NS_DTYPE: - v = tslib.cast_to_nanoseconds(v) + v = conversion.cast_to_nanoseconds(v) if is_datetimetz(v): datetime_tz_items.append((i, k, v)) diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index cbf393046907f..65f4704da3800 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -4,7 +4,7 @@ from pandas._libs import tslib from pandas._libs.tslibs.strptime import array_strptime -from pandas._libs.tslibs import parsing +from pandas._libs.tslibs import parsing, conversion from pandas._libs.tslibs.parsing import ( # noqa parse_time_string, DateParseError, @@ -373,7 +373,7 @@ def _convert_listlike(arg, box, format, name=None, tz=tz): except ValueError as e: try: - values, tz = tslib.datetime_to_datetime64(arg) + values, tz = conversion.datetime_to_datetime64(arg) return DatetimeIndex._simple_new(values, name=name, tz=tz) except (ValueError, TypeError): raise e diff --git a/pandas/tests/indexes/datetimes/test_construction.py b/pandas/tests/indexes/datetimes/test_construction.py index a4706dd8a3767..388b4c606b9e3 100644 --- a/pandas/tests/indexes/datetimes/test_construction.py +++ b/pandas/tests/indexes/datetimes/test_construction.py @@ -9,6 +9,7 @@ import pandas.util.testing as tm from pandas._libs import tslib, lib from pandas._libs.tslib import OutOfBoundsDatetime +from pandas._libs.tslibs import conversion from pandas import (DatetimeIndex, Index, Timestamp, datetime, date_range, to_datetime) @@ -496,7 +497,7 @@ def test_index_cast_datetime64_other_units(self): arr = np.arange(0, 100, 10, dtype=np.int64).view('M8[D]') idx = Index(arr) - assert (idx.values == tslib.cast_to_nanoseconds(arr)).all() + assert (idx.values == conversion.cast_to_nanoseconds(arr)).all() def test_constructor_int64_nocopy(self): # #1624 From 08236be405a1dcda30b524727867b46e077505d4 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 18 Nov 2017 08:41:25 -0800 Subject: [PATCH 2/5] fixup missing return --- pandas/_libs/tslibs/conversion.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 868ec5d12f10d..31fc1900bb8d4 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -149,7 +149,7 @@ cdef inline _to_i8(object val): if is_datetime64_object(val): return get_datetime64_value(val) elif PyDateTime_Check(val): - convert_datetime_to_tsobject(val, None).value + return convert_datetime_to_tsobject(val, None).value return val From f19eebadf54864f16c2871d2f6e3f577f11ed668 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 18 Nov 2017 12:10:51 -0800 Subject: [PATCH 3/5] flake8 fixup --- pandas/tests/indexes/datetimes/test_construction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexes/datetimes/test_construction.py b/pandas/tests/indexes/datetimes/test_construction.py index 388b4c606b9e3..1fc1600f432c4 100644 --- a/pandas/tests/indexes/datetimes/test_construction.py +++ b/pandas/tests/indexes/datetimes/test_construction.py @@ -7,7 +7,7 @@ import pandas as pd from pandas import offsets import pandas.util.testing as tm -from pandas._libs import tslib, lib +from pandas._libs import lib from pandas._libs.tslib import OutOfBoundsDatetime from pandas._libs.tslibs import conversion from pandas import (DatetimeIndex, Index, Timestamp, datetime, date_range, From e156b3f8d8df57afb45f15d29557d8ce99724fc6 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 18 Nov 2017 17:21:46 -0800 Subject: [PATCH 4/5] docstrings, rename per reviewer request --- pandas/_libs/index.pyx | 14 +++++------ pandas/_libs/tslibs/conversion.pxd | 2 +- pandas/_libs/tslibs/conversion.pyx | 39 +++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index ecb315bca2031..c7178c93139d4 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -13,7 +13,7 @@ cimport util import numpy as np -from tslibs.conversion cimport _to_i8 +from tslibs.conversion cimport _maybe_datetimelike_to_i8 from hashtable cimport HashTable @@ -405,12 +405,12 @@ cdef class DatetimeEngine(Int64Engine): if not self.is_unique: return self._get_loc_duplicates(val) values = self._get_index_values() - conv = _to_i8(val) + conv = _maybe_datetimelike_to_i8(val) loc = values.searchsorted(conv, side='left') return util.get_value_at(values, loc) == conv self._ensure_mapping_populated() - return _to_i8(val) in self.mapping + return _maybe_datetimelike_to_i8(val) in self.mapping cdef _get_index_values(self): return self.vgetter().view('i8') @@ -425,12 +425,12 @@ cdef class DatetimeEngine(Int64Engine): # Welcome to the spaghetti factory if self.over_size_threshold and self.is_monotonic_increasing: if not self.is_unique: - val = _to_i8(val) + val = _maybe_datetimelike_to_i8(val) return self._get_loc_duplicates(val) values = self._get_index_values() try: - conv = _to_i8(val) + conv = _maybe_datetimelike_to_i8(val) loc = values.searchsorted(conv, side='left') except TypeError: self._date_check_type(val) @@ -442,7 +442,7 @@ cdef class DatetimeEngine(Int64Engine): self._ensure_mapping_populated() if not self.unique: - val = _to_i8(val) + val = _maybe_datetimelike_to_i8(val) return self._get_loc_duplicates(val) try: @@ -453,7 +453,7 @@ cdef class DatetimeEngine(Int64Engine): pass try: - val = _to_i8(val) + val = _maybe_datetimelike_to_i8(val) return self.mapping.get_item(val) except (TypeError, ValueError): self._date_check_type(val) diff --git a/pandas/_libs/tslibs/conversion.pxd b/pandas/_libs/tslibs/conversion.pxd index 5b0faa02515dc..bf48c98e17298 100644 --- a/pandas/_libs/tslibs/conversion.pxd +++ b/pandas/_libs/tslibs/conversion.pxd @@ -29,4 +29,4 @@ cdef int64_t get_datetime64_nanos(object val) except? -1 cpdef int64_t pydt_to_i8(object pydt) except? -1 -cdef _to_i8(object val) +cdef _maybe_datetimelike_to_i8(object val) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 31fc1900bb8d4..d925433e0df8d 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -75,6 +75,18 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1: def cast_to_nanoseconds(ndarray arr): + """ + Ensure a np.datetime64 array has dtype specifically 'datetime64[ns]' + + Parameters + ---------- + arr : ndarray + + Returns + ------- + result : ndarray with dtype datetime64[ns] + + """ cdef: Py_ssize_t i, n = arr.size ndarray[int64_t] ivalues, iresult @@ -104,6 +116,19 @@ def cast_to_nanoseconds(ndarray arr): def datetime_to_datetime64(ndarray[object] values): + """ + Convert ndarray of datetime-like objects to int64 array representing + nanosecond timestamps. + + Parameters + ---------- + values : ndarray + + Returns + ------- + result : ndarray witth dtype int64 + inferred_tz : tzinfo or None + """ cdef: Py_ssize_t i, n = len(values) object val, inferred_tz = None @@ -140,7 +165,19 @@ def datetime_to_datetime64(ndarray[object] values): return result, inferred_tz -cdef inline _to_i8(object val): +cdef inline _maybe_datetimelike_to_i8(object val): + """ + Try to convert to a nanosecond timestamp. Fall back to returning the + input value. + + Parameters + ---------- + val : object + + Returns + ------- + val : int64 timestamp or original input + """ cdef: pandas_datetimestruct dts try: From 0ef759f2d9a55eba8099467665dd689d57f95c36 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 19 Nov 2017 10:02:10 -0800 Subject: [PATCH 5/5] rename per reviewer request, fix typo --- pandas/_libs/index.pyx | 14 +++++++------- pandas/_libs/tslibs/conversion.pxd | 2 +- pandas/_libs/tslibs/conversion.pyx | 6 +++--- pandas/core/indexes/datetimes.py | 2 +- pandas/core/internals.py | 6 +++--- .../tests/indexes/datetimes/test_construction.py | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index c7178c93139d4..e4c188b28bb6e 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -13,7 +13,7 @@ cimport util import numpy as np -from tslibs.conversion cimport _maybe_datetimelike_to_i8 +from tslibs.conversion cimport maybe_datetimelike_to_i8 from hashtable cimport HashTable @@ -405,12 +405,12 @@ cdef class DatetimeEngine(Int64Engine): if not self.is_unique: return self._get_loc_duplicates(val) values = self._get_index_values() - conv = _maybe_datetimelike_to_i8(val) + conv = maybe_datetimelike_to_i8(val) loc = values.searchsorted(conv, side='left') return util.get_value_at(values, loc) == conv self._ensure_mapping_populated() - return _maybe_datetimelike_to_i8(val) in self.mapping + return maybe_datetimelike_to_i8(val) in self.mapping cdef _get_index_values(self): return self.vgetter().view('i8') @@ -425,12 +425,12 @@ cdef class DatetimeEngine(Int64Engine): # Welcome to the spaghetti factory if self.over_size_threshold and self.is_monotonic_increasing: if not self.is_unique: - val = _maybe_datetimelike_to_i8(val) + val = maybe_datetimelike_to_i8(val) return self._get_loc_duplicates(val) values = self._get_index_values() try: - conv = _maybe_datetimelike_to_i8(val) + conv = maybe_datetimelike_to_i8(val) loc = values.searchsorted(conv, side='left') except TypeError: self._date_check_type(val) @@ -442,7 +442,7 @@ cdef class DatetimeEngine(Int64Engine): self._ensure_mapping_populated() if not self.unique: - val = _maybe_datetimelike_to_i8(val) + val = maybe_datetimelike_to_i8(val) return self._get_loc_duplicates(val) try: @@ -453,7 +453,7 @@ cdef class DatetimeEngine(Int64Engine): pass try: - val = _maybe_datetimelike_to_i8(val) + val = maybe_datetimelike_to_i8(val) return self.mapping.get_item(val) except (TypeError, ValueError): self._date_check_type(val) diff --git a/pandas/_libs/tslibs/conversion.pxd b/pandas/_libs/tslibs/conversion.pxd index bf48c98e17298..6e7df10e7c424 100644 --- a/pandas/_libs/tslibs/conversion.pxd +++ b/pandas/_libs/tslibs/conversion.pxd @@ -29,4 +29,4 @@ cdef int64_t get_datetime64_nanos(object val) except? -1 cpdef int64_t pydt_to_i8(object pydt) except? -1 -cdef _maybe_datetimelike_to_i8(object val) +cdef maybe_datetimelike_to_i8(object val) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index d925433e0df8d..16e88bcaeea3e 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -74,7 +74,7 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1: return ival -def cast_to_nanoseconds(ndarray arr): +def ensure_datetime64ns(ndarray arr): """ Ensure a np.datetime64 array has dtype specifically 'datetime64[ns]' @@ -126,7 +126,7 @@ def datetime_to_datetime64(ndarray[object] values): Returns ------- - result : ndarray witth dtype int64 + result : ndarray with dtype int64 inferred_tz : tzinfo or None """ cdef: @@ -165,7 +165,7 @@ def datetime_to_datetime64(ndarray[object] values): return result, inferred_tz -cdef inline _maybe_datetimelike_to_i8(object val): +cdef inline maybe_datetimelike_to_i8(object val): """ Try to convert to a nanosecond timestamp. Fall back to returning the input value. diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 2c0ef318e7640..64b5b9f958880 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -409,7 +409,7 @@ def __new__(cls, data=None, verify_integrity = False else: if data.dtype != _NS_DTYPE: - subarr = conversion.cast_to_nanoseconds(data) + subarr = conversion.ensure_datetime64ns(data) else: subarr = data else: diff --git a/pandas/core/internals.py b/pandas/core/internals.py index ae2499bbd7047..c5b38851f51fd 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -2463,7 +2463,7 @@ class DatetimeBlock(DatetimeLikeBlockMixin, Block): def __init__(self, values, placement, fastpath=False, **kwargs): if values.dtype != _NS_DTYPE: - values = conversion.cast_to_nanoseconds(values) + values = conversion.ensure_datetime64ns(values) super(DatetimeBlock, self).__init__(values, fastpath=True, placement=placement, **kwargs) @@ -2585,7 +2585,7 @@ def set(self, locs, values, check=False): """ if values.dtype != _NS_DTYPE: # Workaround for numpy 1.6 bug - values = conversion.cast_to_nanoseconds(values) + values = conversion.ensure_datetime64ns(values) self.values[locs] = values @@ -4675,7 +4675,7 @@ def form_blocks(arrays, names, axes): complex_items.append((i, k, v)) elif issubclass(v.dtype.type, np.datetime64): if v.dtype != _NS_DTYPE: - v = conversion.cast_to_nanoseconds(v) + v = conversion.ensure_datetime64ns(v) if is_datetimetz(v): datetime_tz_items.append((i, k, v)) diff --git a/pandas/tests/indexes/datetimes/test_construction.py b/pandas/tests/indexes/datetimes/test_construction.py index 1fc1600f432c4..b59dd25ead57f 100644 --- a/pandas/tests/indexes/datetimes/test_construction.py +++ b/pandas/tests/indexes/datetimes/test_construction.py @@ -497,7 +497,7 @@ def test_index_cast_datetime64_other_units(self): arr = np.arange(0, 100, 10, dtype=np.int64).view('M8[D]') idx = Index(arr) - assert (idx.values == conversion.cast_to_nanoseconds(arr)).all() + assert (idx.values == conversion.ensure_datetime64ns(arr)).all() def test_constructor_int64_nocopy(self): # #1624