58

How to get time difference in seconds from numpy.timedelta64 variable?

time1 = '2012-10-05 04:45:18'
time2 = '2012-10-05 04:44:13'
dt = np.datetime64(time1) - np.datetime64(time2)
print dt

0:01:05

I'd like to convert dt to number (int or float) representing time difference in seconds.

sashkello
  • 17,306
  • 24
  • 81
  • 109

3 Answers3

101

To get number of seconds from numpy.timedelta64() object using numpy 1.7 experimental datetime API:

seconds = dt / np.timedelta64(1, 's')
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • We maybe using different versions? I have `TypeError: function takes at most 1 argument (2 given)` when trying `np.timedelta64(1, 's')` – wim Feb 17 '13 at 23:42
  • 4
    @wim: yes. [1.6 and 1.7 API differ](http://docs.scipy.org/doc/numpy-dev/reference/arrays.datetime.html#datetime-and-timedelta-arithmetic). – jfs Feb 18 '13 at 04:40
  • 14
    For a pandas series, use `series.apply(lambda x: x / timedelta64(1, 's'))` (**NumPy 1.7.1**, **pandas 0.12.0**) – dmvianna Sep 12 '13 at 00:53
  • 11
    another way of applying the same logic to a series: `np.divide(mySeries, np.timedelta64(1, 's'))` is about 70 times faster than the apply method above – fantabolous Aug 20 '14 at 09:05
  • 1
    I get `TypeError: ufunc divide cannot use operands with types dtype(' – Jason S Dec 11 '17 at 19:18
  • @JasonS do you understand the difference between datetime64 and timedelta64 (the difference, look at the code in the question: dt is timedelta64, not datetime64) – jfs Dec 11 '17 at 20:34
47

You can access it through the "wrapped" datetime item:

>>> dt.item().total_seconds()
65.0

Explanation: here dt is an array scalar in numpy, which is a zero rank array or 0-dimensional array. So you will find the dt here also has all the methods an ndarray possesses, and you can do for example dt.astype('float'). But it wraps a python object, in this case a datetime.timedelta object.

To get the original scalar you can use dt.item(). To index the array scalar you can use the somewhat bizarre syntax of getitem using an empty tuple:

>>> dt[()]
array(datetime.timedelta(0, 65), dtype='timedelta64[s]')

This should work in all versions of numpy, but if you are using numpy v1.7+ it may be better to use the newer numpy datetime API directly as explained in the answer from J.F. Sebastien here.

Community
  • 1
  • 1
wim
  • 338,267
  • 99
  • 616
  • 750
  • Thanks, that worked. Can you please explain why dt.seconds doesn't work? – sashkello Feb 17 '13 at 12:11
  • 5
    It's `datetime.timedelta` that has an attribute named like that, not a `numpy.timedelta64`. I don't know why numpy implemented it like that though, maybe someone else can answer .. – wim Feb 17 '13 at 12:19
  • 1
    Worth noting: if the `timedelta64` object is of dtype `timedelta64[ns]` this will not work, you need to cast to `timedelta64[s]` first (i.e. `dt.astype('timedelta64[s]').item().total_seconds()`). I've been bitten by this so many times – leifdenby Apr 14 '21 at 13:47
8

You can simply cast the value to the desired time unit using np.astype, as shown in the example:

timedelta = np.datetime64('2011-07-18')-np.datetime64('2011-07-16')
seconds = timedelta.astype('timedelta64[s]').astype(np.int32)
hours = timedelta.astype('timedelta64[h]').astype(np.int32)
Dema
  • 301
  • 2
  • 5
  • 2
    `timedelta.astype('timedelta64[s]')` seems to truncate millisecond precision to me `` [147] elapsed_time.iloc[0] Timedelta('0 days 00:00:00.005322600') [148] elapsed_time.iloc[0]/ np.timedelta64(1, 's') 0.0053226 [149] elapsed_time.astype('timedelta64[s]').astype(np.float64).iloc[0] 0.0 `` – alexandre iolov Jan 25 '21 at 15:17
  • Nice - missed the intermediate type conversion – jtlz2 Feb 05 '21 at 13:44