diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index b71edcf1f6f51..851c1a3fbd6e9 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -655,6 +655,7 @@ Datetimelike - Bug in :class:`DatetimeIndex` incorrectly allowing indexing with ``Timedelta`` object (:issue:`20464`) - Bug in :class:`DatetimeIndex` where frequency was being set if original frequency was ``None`` (:issue:`22150`) - Bug in rounding methods of :class:`DatetimeIndex` (:meth:`~DatetimeIndex.round`, :meth:`~DatetimeIndex.ceil`, :meth:`~DatetimeIndex.floor`) and :class:`Timestamp` (:meth:`~Timestamp.round`, :meth:`~Timestamp.ceil`, :meth:`~Timestamp.floor`) could give rise to loss of precision (:issue:`22591`) +- Bug in :func:`to_datetime` with an :class:`Index` argument that would drop the ``name`` from the result (:issue:`21697`) Timedelta ^^^^^^^^^ diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index 57387b9ea870a..4a5290a90313d 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -99,13 +99,13 @@ def _convert_and_box_cache(arg, cache_array, box, errors, name=None): result = Series(arg).map(cache_array) if box: if errors == 'ignore': - return Index(result) + return Index(result, name=name) else: return DatetimeIndex(result, name=name) return result.values -def _return_parsed_timezone_results(result, timezones, box, tz): +def _return_parsed_timezone_results(result, timezones, box, tz, name): """ Return results from array_strptime if a %z or %Z directive was passed. @@ -119,6 +119,9 @@ def _return_parsed_timezone_results(result, timezones, box, tz): True boxes result as an Index-like, False returns an ndarray tz : object None or pytz timezone object + name : string, default None + Name for a DatetimeIndex + Returns ------- tz_result : ndarray of parsed dates with timezone @@ -136,7 +139,7 @@ def _return_parsed_timezone_results(result, timezones, box, tz): in zip(result, timezones)]) if box: from pandas import Index - return Index(tz_results) + return Index(tz_results, name=name) return tz_results @@ -209,7 +212,7 @@ def _convert_listlike_datetimes(arg, box, format, name=None, tz=None, if box: if errors == 'ignore': from pandas import Index - return Index(result) + return Index(result, name=name) return DatetimeIndex(result, tz=tz, name=name) return result @@ -252,7 +255,7 @@ def _convert_listlike_datetimes(arg, box, format, name=None, tz=None, arg, format, exact=exact, errors=errors) if '%Z' in format or '%z' in format: return _return_parsed_timezone_results( - result, timezones, box, tz) + result, timezones, box, tz, name) except tslibs.OutOfBoundsDatetime: if errors == 'raise': raise diff --git a/pandas/tests/indexes/datetimes/test_tools.py b/pandas/tests/indexes/datetimes/test_tools.py index cc6db8f5854c8..3b7d6a709230b 100644 --- a/pandas/tests/indexes/datetimes/test_tools.py +++ b/pandas/tests/indexes/datetimes/test_tools.py @@ -233,6 +233,15 @@ def test_to_datetime_parse_timezone_malformed(self, offset): with pytest.raises(ValueError): pd.to_datetime([date], format=fmt) + def test_to_datetime_parse_timezone_keeps_name(self): + # GH 21697 + fmt = '%Y-%m-%d %H:%M:%S %z' + arg = pd.Index(['2010-01-01 12:00:00 Z'], name='foo') + result = pd.to_datetime(arg, format=fmt) + expected = pd.DatetimeIndex(['2010-01-01 12:00:00'], tz='UTC', + name='foo') + tm.assert_index_equal(result, expected) + class TestToDatetime(object): def test_to_datetime_pydatetime(self): @@ -765,6 +774,14 @@ def test_unit_rounding(self, cache): expected = pd.Timestamp('2015-06-19 19:55:31.877000093') assert result == expected + @pytest.mark.parametrize('cache', [True, False]) + def test_unit_ignore_keeps_name(self, cache): + # GH 21697 + expected = pd.Index([15e9] * 2, name='name') + result = pd.to_datetime(expected, errors='ignore', box=True, unit='s', + cache=cache) + tm.assert_index_equal(result, expected) + @pytest.mark.parametrize('cache', [True, False]) def test_dataframe(self, cache):