Skip to content

Commit 862d62d

Browse files
committed
ENH: support NaT values into datetime series for interpolation (pandas-dev#11701)
1 parent 5d0daa0 commit 862d62d

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Other Enhancements
8484
- :meth:`Series.nlargest`, :meth:`Series.nsmallest`, :meth:`DataFrame.nlargest`, and :meth:`DataFrame.nsmallest` now accept the value ``"all"`` for the ``keep`` argument. This keeps all ties for the nth largest/smallest value (:issue:`16818`)
8585
- :class:`IntervalIndex` has gained the :meth:`~IntervalIndex.set_closed` method to change the existing ``closed`` value (:issue:`21670`)
8686
- :func:`~DataFrame.to_csv` and :func:`~DataFrame.to_json` now support ``compression='infer'`` to infer compression based on filename (:issue:`15008`)
87+
- Implement interpolating ``NaT`` values in ``datetime`` series (:issue:`11701`)
8788
-
8889

8990
.. _whatsnew_0240.api_breaking:

pandas/core/generic.py

+13
Original file line numberDiff line numberDiff line change
@@ -6112,6 +6112,14 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False,
61126112
raise NotImplementedError("Interpolation with NaNs in the index "
61136113
"has not been implemented. Try filling "
61146114
"those NaNs before interpolating.")
6115+
is_datetime = False
6116+
datetime_timezone = None
6117+
if is_datetime64_any_dtype(_maybe_transposed_self):
6118+
_datetime_nat_values = _maybe_transposed_self.isnull()
6119+
datetime_timezone = _maybe_transposed_self.dt.tz
6120+
_maybe_transposed_self = _maybe_transposed_self.astype('int')
6121+
_maybe_transposed_self[_datetime_nat_values] = np.nan
6122+
is_datetime = True
61156123
data = _maybe_transposed_self._data
61166124
new_data = data.interpolate(method=method, axis=ax, index=index,
61176125
values=_maybe_transposed_self, limit=limit,
@@ -6120,6 +6128,11 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False,
61206128
inplace=inplace, downcast=downcast,
61216129
**kwargs)
61226130

6131+
if is_datetime:
6132+
new_data = self._constructor(new_data)
6133+
new_data = pd.to_datetime(new_data, utc=True).dt.tz_convert(
6134+
datetime_timezone)
6135+
61236136
if inplace:
61246137
if axis == 1:
61256138
new_data = self._constructor(new_data).T._data

pandas/tests/series/test_missing.py

+20
Original file line numberDiff line numberDiff line change
@@ -1317,3 +1317,23 @@ def test_series_interpolate_intraday(self):
13171317
result = ts.reindex(new_index).interpolate(method='time')
13181318

13191319
tm.assert_numpy_array_equal(result.values, exp.values)
1320+
1321+
def test_series_interpolate_nat(self):
1322+
# GH 11701
1323+
for tz in [None, 'UTC', 'Europe/Paris']:
1324+
expected = pd.Series(pd.date_range('2015-01-01',
1325+
'2015-01-30', tz=tz))
1326+
result = expected.copy()
1327+
result[[3, 4, 5, 13, 14, 15]] = pd.NaT
1328+
result = result.interpolate()
1329+
tm.assert_series_equal(result, expected)
1330+
1331+
def test_series_interpolate_nat_inplace(self):
1332+
# GH 11701
1333+
for tz in [None, 'UTC', 'Europe/Paris']:
1334+
expected = pd.Series(pd.date_range('2015-01-01',
1335+
'2015-01-30', tz=tz))
1336+
result = expected.copy()
1337+
result[[3, 4, 5, 13, 14, 15]] = pd.NaT
1338+
result.interpolate(inplace=True)
1339+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)