diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index f88114e1c9e20..5f2fc17b08ac6 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -2240,24 +2240,11 @@ class DatetimeTZBlock(ExtensionBlock, DatetimeBlock): is_datetimetz = True is_extension = True - def __init__(self, values, placement, ndim=2, dtype=None): - # XXX: This will end up calling _maybe_coerce_values twice - # when dtype is not None. It's relatively cheap (just an isinstance) - # but it'd nice to avoid. - # - # If we can remove dtype from __init__, and push that conversion - # push onto the callers, then we can remove this entire __init__ - # and just use DatetimeBlock's. - if dtype is not None: - values = self._maybe_coerce_values(values, dtype=dtype) - super(DatetimeTZBlock, self).__init__(values, placement=placement, - ndim=ndim) - @property def _holder(self): return DatetimeArray - def _maybe_coerce_values(self, values, dtype=None): + def _maybe_coerce_values(self, values): """Input validation for values passed to __init__. Ensure that we have datetime64TZ, coercing if necessary. @@ -2265,19 +2252,14 @@ def _maybe_coerce_values(self, values, dtype=None): ----------- values : array-like Must be convertible to datetime64 - dtype : string or DatetimeTZDtype, optional - Does a shallow copy to this tz Returns ------- - values : ndarray[datetime64ns] + values : DatetimeArray """ if not isinstance(values, self._holder): values = self._holder(values) - if dtype is not None: - values = type(values)(values, dtype=dtype) - if values.tz is None: raise ValueError("cannot create a DatetimeTZBlock without a tz") @@ -3087,8 +3069,9 @@ def make_block(values, placement, klass=None, ndim=None, dtype=None, klass = get_block_type(values, dtype) elif klass is DatetimeTZBlock and not is_datetime64tz_dtype(values): - return klass(values, ndim=ndim, - placement=placement, dtype=dtype) + # TODO: This is no longer hit internally; does it need to be retained + # for e.g. pyarrow? + values = DatetimeArray(values, dtype) return klass(values, ndim=ndim, placement=placement) diff --git a/pandas/io/packers.py b/pandas/io/packers.py index e6d18d5d4193a..b83eab7d0eba0 100644 --- a/pandas/io/packers.py +++ b/pandas/io/packers.py @@ -53,14 +53,15 @@ BadMove as _BadMove, move_into_mutable_buffer as _move_into_mutable_buffer) from pandas.core.dtypes.common import ( - is_categorical_dtype, is_object_dtype, needs_i8_conversion, pandas_dtype) + is_categorical_dtype, is_datetime64tz_dtype, is_object_dtype, + needs_i8_conversion, pandas_dtype) from pandas import ( # noqa:F401 Categorical, CategoricalIndex, DataFrame, DatetimeIndex, Float64Index, Index, Int64Index, Interval, IntervalIndex, MultiIndex, NaT, Panel, Period, PeriodIndex, RangeIndex, Series, TimedeltaIndex, Timestamp) from pandas.core import internals -from pandas.core.arrays import IntervalArray, PeriodArray +from pandas.core.arrays import DatetimeArray, IntervalArray, PeriodArray from pandas.core.arrays.sparse import BlockIndex, IntIndex from pandas.core.generic import NDFrame from pandas.core.internals import BlockManager, _safe_reshape, make_block @@ -651,6 +652,12 @@ def create_block(b): placement = b[u'locs'] else: placement = axes[0].get_indexer(b[u'items']) + + if is_datetime64tz_dtype(b[u'dtype']): + assert isinstance(values, np.ndarray), type(values) + assert values.dtype == 'M8[ns]', values.dtype + values = DatetimeArray(values, dtype=b[u'dtype']) + return make_block(values=values, klass=getattr(internals, b[u'klass']), placement=placement,