Search code examples
pythondatetimepython-xarraytimedelta

Cannot reach timedelta64 Object in xArray in Python


I have some xArrays with time info and want to calculate the range:

data[0].time.max() - data[0].time.min()

which returns a xarray.DataArray with one element: array(14393250000000, dtype='timedelta64[ns]')

However if I want to compare it to a different timedelta e.g.

(data[0].time.max() - data[0].time.min()) > datetime.timedelta(minutes=1)

I get TypeError: '>' not supported between instances of 'int' and 'datetime.timedelta'

I tried extracting the object out of the array like so:

(data[0].time.max() - data[0].time.min()).item() > datetime.timedelta(minutes=1)

Same result.

I tried converting it to a datetime.timedelta object like so:

#alternative 1
time_diff = np.array([data[0].time.max() - data[0].time.min()], dtype='timedelta64[ns]')[0]

#alternative 2
time_diff = np.array([data[0].time.max() - data[0].time.min()])[0]

time_diff_dt = datetime.timedelta(microseconds=time_diff / 1000)
time_diff_dt > datetime.timedelta(minutes=1)

Both alternatives return ValueError: Could not convert object to NumPy timedelta


Solution

  • Looks like the issue here is that xarray gives you a np.timedelta64 which you are trying to compare with a datetime.timedelta object. So you will need to convert one to the other to make the comparison.

    Further, your np.timedelta64 has ns precision, whereas Python's datetime only goes down to microsecond precision. This is why the .item() (which usually should convert np.timedelta64 to datetime.timedelta) is not behaving as you desire.

    To resolve this, you can try converting to microseconds first:

    diff = data[0].time.max() - data[0].time.min()  # This has type timedelta64[ns]
    diff = diff.astype('timedelta64[us]')  # Convert to microsecond precision
    diff = diff.item()  # Convert to Python datetime.timedelta
    diff > datetime.timedelta(minutes=1)  # Now we can compare like objects
    

    Alternatively, compare vs np.timedelta64(1, 'm') instead of datetime.timedelta(minutes=1).