Skip to content

Document cftime arithmetic limitations #7381

@larsbuntemeyer

Description

@larsbuntemeyer

What is your issue?

Hey all,
i have quick use case where i am unsure if that's related to xarray. I just want to do simple arithmetics with a cftime time axis, e.g.

import xarray as xr
import numpy as np
time = xr.DataArray(xr.cftime_range(start="2000", periods=6, freq="1MS", calendar="noleap"), dims='time')

and then, e.g., compute mid of those timesteps:

time[:-1] + 0.5 * time.diff('time')

which results in

---------------------------------------------------------------------------
UFuncTypeError                            Traceback (most recent call last)
Input In [72], in <cell line: 1>()
----> 1 time[1:] + 0.5 * time.diff('time')

File /work/ch0636/g300046/conda_envs/pyremo-dev/lib/python3.9/site-packages/xarray/core/_typed_ops.py:206, in DataArrayOpsMixin.__add__(self, other)
    205 def __add__(self, other):
--> 206     return self._binary_op(other, operator.add)

File /work/ch0636/g300046/conda_envs/pyremo-dev/lib/python3.9/site-packages/xarray/core/dataarray.py:3530, in DataArray._binary_op(self, other, f, reflexive)
   3526 other_variable = getattr(other, "variable", other)
   3527 other_coords = getattr(other, "coords", None)
   3529 variable = (
-> 3530     f(self.variable, other_variable)
   3531     if not reflexive
   3532     else f(other_variable, self.variable)
   3533 )
   3534 coords, indexes = self.coords._merge_raw(other_coords, reflexive)
   3535 name = self._result_name(other)

File /work/ch0636/g300046/conda_envs/pyremo-dev/lib/python3.9/site-packages/xarray/core/_typed_ops.py:396, in VariableOpsMixin.__add__(self, other)
    395 def __add__(self, other):
--> 396     return self._binary_op(other, operator.add)

File /work/ch0636/g300046/conda_envs/pyremo-dev/lib/python3.9/site-packages/xarray/core/variable.py:2519, in Variable._binary_op(self, other, f, reflexive)
   2516 attrs = self._attrs if keep_attrs else None
   2517 with np.errstate(all="ignore"):
   2518     new_data = (
-> 2519         f(self_data, other_data) if not reflexive else f(other_data, self_data)
   2520     )
   2521 result = Variable(dims, new_data, attrs=attrs)
   2522 return result

UFuncTypeError: ufunc 'add' cannot use operands with types dtype('O') and dtype('<m8[ns]')

The problem is the differentiation results in np.timedelta64 objects:

time.diff('time')

grafik
with which the arithmetics are not implemented in cftime. However, differentiation with datetime.timdelta (which is wrapped by np.timedelta64) works in this case since it's implemented in cftime, e.g., when i do np.diff, it works:

time[:-1] + 0.5 * np.diff(time)

grafik

i get the expected result. I am not sure what to expect from xarray and if this might be an issue of cftime (e.g., implement differentiation with np.timedelta64). I was wondering why the differentiation with cftime objects results in np.timedelta64 and not datetime.timedelta objects (like in the pure numpy differentation).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions