diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 9db8bef8debcd..3bc0f633c65dd 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -423,6 +423,7 @@ Reshaping - Bug in :func:`merge` where merging with equivalent Categorical dtypes was raising an error (:issue:`22501`) - bug in :class:`DataFrame` instantiating with a ``range`` (e.g. ``pd.DataFrame(range(3))``) raised an error (:issue:`26342`). - Bug in :class:`DataFrame` constructor when passing non-empty tuples would cause a segmentation fault (:issue:`25691`) +- Bug in :func:`Series.apply` failed when the series is a timezone aware :class:`DatetimeIndex` (:issue:`25959`) - Bug in :func:`pandas.cut` where large bins could incorrectly raise an error due to an integer overflow (:issue:`26045`) - Bug in :func:`DataFrame.sort_index` where an error is thrown when a multi-indexed DataFrame is sorted on all levels with the initial level sorted last (:issue:`26053`) - Bug in :meth:`Series.nlargest` treats ``True`` as smaller than ``False`` (:issue:`26154`) diff --git a/pandas/core/series.py b/pandas/core/series.py index f0b674596656a..f0a21637699f2 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -28,6 +28,7 @@ from pandas.core.dtypes.missing import ( isna, na_value_for_dtype, notna, remove_na_arraylike) +import pandas as pd from pandas.core import algorithms, base, generic, nanops, ops from pandas.core.accessor import CachedAccessor from pandas.core.arrays import ExtensionArray, SparseArray @@ -3702,8 +3703,10 @@ def f(x): mapped = lib.map_infer(values, f, convert=convert_dtype) if len(mapped) and isinstance(mapped[0], Series): - from pandas.core.frame import DataFrame - return DataFrame(mapped.tolist(), index=self.index) + # GH 25959 use pd.array instead of tolist + # so extension arrays can be used + return self._constructor_expanddim(pd.array(mapped), + index=self.index) else: return self._constructor(mapped, index=self.index).__finalize__(self) diff --git a/pandas/tests/series/test_apply.py b/pandas/tests/series/test_apply.py index 181df107dd8d5..4551453499455 100644 --- a/pandas/tests/series/test_apply.py +++ b/pandas/tests/series/test_apply.py @@ -671,3 +671,23 @@ def test_map_missing_mixed(self, vals, mapping, exp): result = s.map(mapping) tm.assert_series_equal(result, pd.Series(exp)) + + @pytest.mark.parametrize("dti,exp", [ + (Series([1, 2], index=pd.DatetimeIndex([0, 31536000000])), + DataFrame(np.repeat([[1, 2]], 2, axis=0), dtype='int64')), + (tm.makeTimeSeries(nper=30), + DataFrame(np.repeat([[1, 2]], 30, axis=0), dtype='int64')) + ]) + def test_apply_series_on_date_time_index_aware_series(self, dti, exp): + # GH 25959 + # Calling apply on a localized time series should not cause an error + index = dti.tz_localize('UTC').index + result = pd.Series(index).apply(lambda x: pd.Series([1, 2])) + assert_frame_equal(result, exp) + + def test_apply_scaler_on_date_time_index_aware_series(self): + # GH 25959 + # Calling apply on a localized time series should not cause an error + series = tm.makeTimeSeries(nper=30).tz_localize('UTC') + result = pd.Series(series.index).apply(lambda x: 1) + assert_series_equal(result, pd.Series(np.ones(30), dtype='int64'))