Repository: pandas-dev/pandas

Issue:
interpolate w/ method=time does not work with timedeltas
```
In [98]: pd.DataFrame({'v':[1,2,3]},index=pd.to_timedelta([1,2,3], unit="d")).interpolate(method="time")

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-98-9c399944f329> in <module>()
----> 1 pd.DataFrame({'v':[1,2,3]},index=pd.to_timedelta([1,2,3], unit="d")).interpolate(method="time")

/usr/lib64/python2.7/site-packages/pandas/core/generic.py in interpolate(self, method, axis, limit, inplace, downcast, **kwargs)
   2530                                           inplace=inplace,
   2531                                           downcast=downcast,
-> 2532                                           **kwargs)
   2533 
   2534         if inplace:

/usr/lib64/python2.7/site-packages/pandas/core/internals.py in interpolate(self, *args, **kwargs)
   2402 
   2403     def interpolate(self, *args, **kwargs):
-> 2404         return self.apply('interpolate', *args, **kwargs)
   2405 
   2406     def shift(self, *args, **kwargs):

/usr/lib64/python2.7/site-packages/pandas/core/internals.py in apply(self, f, *args, **kwargs)
   2373 
   2374             else:
-> 2375                 applied = getattr(blk, f)(*args, **kwargs)
   2376 
   2377             if isinstance(applied, list):

/usr/lib64/python2.7/site-packages/pandas/core/internals.py in interpolate(self, method, axis, index, values, inplace, limit, fill_value, coerce, downcast, **kwargs)
    819                                      inplace=inplace,
    820                                      downcast=downcast,
--> 821                                      **kwargs)
    822 
    823         raise ValueError("invalid method '{0}' to interpolate.".format(method))

/usr/lib64/python2.7/site-packages/pandas/core/internals.py in _interpolate(self, method, index, values, fill_value, axis, limit, inplace, downcast, **kwargs)
    880 
    881         # interp each column independently
--> 882         interp_values = np.apply_along_axis(func, axis, data)
    883 
    884         blocks = [make_block(interp_values, self.items, self.ref_items,

/usr/lib64/python2.7/site-packages/numpy/lib/shape_base.pyc in apply_along_axis(func1d, axis, arr, *args)
     77     outshape = asarray(arr.shape).take(indlist)
     78     i.put(indlist, ind)
---> 79     res = func1d(arr[tuple(i.tolist())],*args)
     80     #  if res is a number, then we have a smaller output array
     81     if isscalar(res):

/usr/lib64/python2.7/site-packages/pandas/core/internals.py in func(x)
    877             return com.interpolate_1d(index, x, method=method, limit=limit,
    878                                       fill_value=fill_value,
--> 879                                       bounds_error=False, **kwargs)
    880 
    881         # interp each column independently

/usr/lib64/python2.7/site-packages/pandas/core/common.py in interpolate_1d(xvalues, yvalues, method, limit, fill_value, bounds_error, **kwargs)
   1362         if not getattr(xvalues, 'is_all_dates', None):
   1363         # if not issubclass(xvalues.dtype.type, np.datetime64):
-> 1364             raise ValueError('time-weighted interpolation only works '
   1365                              'on Series or DataFrames with a '
   1366                              'DatetimeIndex')

ValueError: time-weighted interpolation only works on Series or DataFrames with a DatetimeIndex
```



Discussion:
unless their is real interest, won't do this

Can we leave this open then and mark as milestone "Someday"?

came up on SO http://stackoverflow.com/q/34315753/1240268

Run into this today as well.

I have also run into this today.

If someone is interested in working on this, it'd follow a similar pattern to https://github.com/pandas-dev/pandas/pull/14737 (convert to i8, interpolate, convert back to timedelta).
@TomAugspurger i can take this up post #14737 :)
@TomAugspurger is this still an issue? when i run the code fragment given in the initial post of this issue, i get this output

>>> pd.DataFrame({'v':[1,2,3]},index=pd.to_timedelta([1,2,3], unit="d")).interpolate(method="time")
            v
1 days  1
2 days  2
3 days  3


I filed this a long time ago, so bear with me. This does not seem to work:
```python
pd.DataFrame({'v':[1,np.nan,5]},index=pd.to_timedelta([1,2,3], unit="d")).interpolate(method="time")
```
whereas this does:
```python
pd.DataFrame({'v':[1,np.nan,5]},index=pd.to_datetime([1,2,3], unit="d")).interpolate(method="time")
```
I am seeing the same issue as in the above linked SO post.
@cancan101 so it fails when we try to pass timedelta, is that correct?
What do you mean?
This line works fine:
```python
pd.DataFrame({'v':[1,np.nan,5]},index=pd.to_timedelta([1,2,3], unit="d"))
```
@cancan101 yes that is fine, what i am trying to say is that it fails when you try to interpolate the timedelta data, 

pd.DataFrame({'v':[1,np.nan,5]},index=pd.to_timedelta([1,2,3], unit="d")).interpolate(method="time")

whereas when you call interpolate for datetime data, it works. That is the difference between the two lines that you've posted earlier (as examples of what works and what doesnt), right?

yes

Resolving patch:
diff --git a/pandas/core/missing.py b/pandas/core/missing.py
--- a/pandas/core/missing.py
+++ b/pandas/core/missing.py
@@ -12,7 +12,8 @@
                                  is_float_dtype, is_datetime64_dtype,
                                  is_integer_dtype, _ensure_float64,
                                  is_scalar,
-                                 _DATELIKE_DTYPES)
+                                 _DATELIKE_DTYPES,
+                                 needs_i8_conversion)
 from pandas.types.missing import isnull
 
 
@@ -187,7 +188,7 @@ def _interp_limit(invalid, fw_limit, bw_limit):
         if method in ('values', 'index'):
             inds = np.asarray(xvalues)
             # hack for DatetimeIndex, #1646
-            if issubclass(inds.dtype.type, np.datetime64):
+            if needs_i8_conversion(inds.dtype.type):
                 inds = inds.view(np.int64)
             if inds.dtype == np.object_:
                 inds = lib.maybe_convert_objects(inds)


Test patch:
diff --git a/pandas/tests/series/test_missing.py b/pandas/tests/series/test_missing.py
--- a/pandas/tests/series/test_missing.py
+++ b/pandas/tests/series/test_missing.py
@@ -891,6 +891,23 @@ def test_spline_error(self):
         with tm.assertRaises(ValueError):
             s.interpolate(method='spline', order=0)
 
+    def test_interp_timedelta64(self):
+        # GH 6424
+        df = Series([1, np.nan, 3],
+                    index=pd.to_timedelta([1, 2, 3]))
+        result = df.interpolate(method='time')
+        expected = Series([1., 2., 3.],
+                          index=pd.to_timedelta([1, 2, 3]))
+        assert_series_equal(result, expected)
+
+        # test for non uniform spacing
+        df = Series([1, np.nan, 3],
+                    index=pd.to_timedelta([1, 2, 4]))
+        result = df.interpolate(method='time')
+        expected = Series([1., 1.666667, 3.],
+                          index=pd.to_timedelta([1, 2, 4]))
+        assert_series_equal(result, expected)
+
 
 if __name__ == '__main__':
     import nose