Skip to content

Commit ee0c92c

Browse files
committed
Merge pull request #5305 from jreback/astype_td
ENH: allow astype conversions for timedeltas to other timedelta freqs (still returns a float series), related to GH4521
2 parents d6378c4 + def22c4 commit ee0c92c

File tree

5 files changed

+28
-7
lines changed

5 files changed

+28
-7
lines changed

doc/source/release.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ Improvements to existing features
118118
by an integer series (:issue`4521`)
119119
- A Series of dtype ``timedelta64[ns]`` can now be divided by another
120120
``timedelta64[ns]`` object to yield a ``float64`` dtyped Series. This
121-
is frequency conversion.
121+
is frequency conversion; astyping is also supported.
122122
- Timedelta64 support ``fillna/ffill/bfill`` with an integer interpreted as seconds,
123123
or a ``timedelta`` (:issue:`3371`)
124124
- Box numeric ops on ``timedelta`` Series (:issue:`4984`)

doc/source/timeseries.rst

+4-2
Original file line numberDiff line numberDiff line change
@@ -1285,8 +1285,8 @@ It can also construct Series.
12851285
12861286
**frequency conversion**
12871287

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

12911291
.. ipython:: python
12921292
@@ -1297,9 +1297,11 @@ These operations yield ``float64`` dtyped Series.
12971297
12981298
# to days
12991299
td / np.timedelta64(1,'D')
1300+
td.astype('timedelta64[D]')
13001301
13011302
# to seconds
13021303
td / np.timedelta64(1,'s')
1304+
td.astype('timedelta64[s]')
13031305
13041306
Dividing or multiplying a ``timedelta64[ns]`` Series by an integer or integer Series
13051307
yields another ``timedelta64[ns]`` dtypes Series.

doc/source/v0.13.0.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ Enhancements
357357
to_timedelta(np.arange(5),unit='d')
358358

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

363363
.. ipython:: python
@@ -370,9 +370,11 @@ Enhancements
370370

371371
# to days
372372
td / np.timedelta64(1,'D')
373+
td.astype('timedelta64[D]')
373374

374375
# to seconds
375376
td / np.timedelta64(1,'s')
377+
td.astype('timedelta64[s]')
376378

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

pandas/core/common.py

+9
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,16 @@ def _astype_nansafe(arr, dtype, copy=True):
20432043

20442044
# in py3, timedelta64[ns] are int64
20452045
elif (compat.PY3 and dtype not in [_INT64_DTYPE,_TD_DTYPE]) or (not compat.PY3 and dtype != _TD_DTYPE):
2046+
2047+
# allow frequency conversions
2048+
if dtype.kind == 'm':
2049+
mask = isnull(arr)
2050+
result = arr.astype(dtype).astype(np.float64)
2051+
result[mask] = np.nan
2052+
return result
2053+
20462054
raise TypeError("cannot astype a timedelta from [%s] to [%s]" % (arr.dtype,dtype))
2055+
20472056
return arr.astype(_TD_DTYPE)
20482057
elif (np.issubdtype(arr.dtype, np.floating) and
20492058
np.issubdtype(dtype, np.integer)):

pandas/tests/test_series.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -2128,9 +2128,9 @@ def test_constructor_dtype_timedelta64(self):
21282128
for i in range(3)] + [np.nan ], dtype='m8[ns]' )
21292129
self.assert_(td.dtype == 'timedelta64[ns]')
21302130

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

21352135
# valid astype
21362136
td.astype('int64')
@@ -2371,10 +2371,18 @@ def test_timedelta64_conversions(self):
23712371

23722372
for m in [1, 3, 10]:
23732373
for unit in ['D','h','m','s','ms','us','ns']:
2374+
2375+
# op
23742376
expected = s1.apply(lambda x: x / np.timedelta64(m,unit))
23752377
result = s1 / np.timedelta64(m,unit)
23762378
assert_series_equal(result, expected)
23772379

2380+
if m == 1 and unit != 'ns':
2381+
2382+
# astype
2383+
result = s1.astype("timedelta64[{0}]".format(unit))
2384+
assert_series_equal(result, expected)
2385+
23782386
# reverse op
23792387
expected = s1.apply(lambda x: np.timedelta64(m,unit) / x)
23802388
result = np.timedelta64(m,unit) / s1

0 commit comments

Comments
 (0)