Skip to content

ENH: allow astype conversions for timedeltas to other timedelta freqs (still returns a float series), related to GH4521 #5305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/release.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Improvements to existing features
by an integer series (:issue`4521`)
- A Series of dtype ``timedelta64[ns]`` can now be divided by another
``timedelta64[ns]`` object to yield a ``float64`` dtyped Series. This
is frequency conversion.
is frequency conversion; astyping is also supported.
- Timedelta64 support ``fillna/ffill/bfill`` with an integer interpreted as seconds,
or a ``timedelta`` (:issue:`3371`)
- Box numeric ops on ``timedelta`` Series (:issue:`4984`)
Expand Down
6 changes: 4 additions & 2 deletions doc/source/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1285,8 +1285,8 @@ It can also construct Series.

**frequency conversion**

Timedeltas can be converted to other 'frequencies' by dividing by another timedelta.
These operations yield ``float64`` dtyped Series.
Timedeltas can be converted to other 'frequencies' by dividing by another timedelta,
or by astyping to a specific timedelta type. These operations yield ``float64`` dtyped Series.

.. ipython:: python

Expand All @@ -1297,9 +1297,11 @@ These operations yield ``float64`` dtyped Series.

# to days
td / np.timedelta64(1,'D')
td.astype('timedelta64[D]')

# to seconds
td / np.timedelta64(1,'s')
td.astype('timedelta64[s]')

Dividing or multiplying a ``timedelta64[ns]`` Series by an integer or integer Series
yields another ``timedelta64[ns]`` dtypes Series.
Expand Down
4 changes: 3 additions & 1 deletion doc/source/v0.13.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ Enhancements
to_timedelta(np.arange(5),unit='d')

A Series of dtype ``timedelta64[ns]`` can now be divided by another
``timedelta64[ns]`` object to yield a ``float64`` dtyped Series. This
``timedelta64[ns]`` object, or astyped to yield a ``float64`` dtyped Series. This
is frequency conversion. See :ref:`the docs<timeseries.timedeltas_convert>` for the docs.

.. ipython:: python
Expand All @@ -370,9 +370,11 @@ Enhancements

# to days
td / np.timedelta64(1,'D')
td.astype('timedelta64[D]')

# to seconds
td / np.timedelta64(1,'s')
td.astype('timedelta64[s]')

Dividing or multiplying a ``timedelta64[ns]`` Series by an integer or integer Series

Expand Down
9 changes: 9 additions & 0 deletions pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2043,7 +2043,16 @@ def _astype_nansafe(arr, dtype, copy=True):

# in py3, timedelta64[ns] are int64
elif (compat.PY3 and dtype not in [_INT64_DTYPE,_TD_DTYPE]) or (not compat.PY3 and dtype != _TD_DTYPE):

# allow frequency conversions
if dtype.kind == 'm':
mask = isnull(arr)
result = arr.astype(dtype).astype(np.float64)
result[mask] = np.nan
return result

raise TypeError("cannot astype a timedelta from [%s] to [%s]" % (arr.dtype,dtype))

return arr.astype(_TD_DTYPE)
elif (np.issubdtype(arr.dtype, np.floating) and
np.issubdtype(dtype, np.integer)):
Expand Down
14 changes: 11 additions & 3 deletions pandas/tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -2128,9 +2128,9 @@ def test_constructor_dtype_timedelta64(self):
for i in range(3)] + [np.nan ], dtype='m8[ns]' )
self.assert_(td.dtype == 'timedelta64[ns]')

# invalid astypes
for t in ['s', 'D', 'us', 'ms']:
self.assertRaises(TypeError, td.astype, 'm8[%s]' % t)
# these are frequency conversion astypes
#for t in ['s', 'D', 'us', 'ms']:
# self.assertRaises(TypeError, td.astype, 'm8[%s]' % t)

# valid astype
td.astype('int64')
Expand Down Expand Up @@ -2371,10 +2371,18 @@ def test_timedelta64_conversions(self):

for m in [1, 3, 10]:
for unit in ['D','h','m','s','ms','us','ns']:

# op
expected = s1.apply(lambda x: x / np.timedelta64(m,unit))
result = s1 / np.timedelta64(m,unit)
assert_series_equal(result, expected)

if m == 1 and unit != 'ns':

# astype
result = s1.astype("timedelta64[{0}]".format(unit))
assert_series_equal(result, expected)

# reverse op
expected = s1.apply(lambda x: np.timedelta64(m,unit) / x)
result = np.timedelta64(m,unit) / s1
Expand Down