pytensor icon indicating copy to clipboard operation
pytensor copied to clipboard

ENH: support datetime64[ns] dtype

Open ferrine opened this issue 2 years ago • 3 comments

Before

index = array(['2017-06-02T00:00:00.000000000', '2017-06-03T00:00:00.000000000',
       '2017-06-04T00:00:00.000000000', ...,
       '2021-06-28T00:00:00.000000000', '2021-06-29T00:00:00.000000000',
       '2021-06-30T00:00:00.000000000'], dtype='datetime64[ns]')

pt.as_tensor(index)

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File .venv/lib/python3.10/site-packages/pytensor/tensor/type.py:287, in TensorType.dtype_specs(self)
    286 try:
--> 287     return self.dtype_specs_map[self.dtype]
    288 except KeyError:

KeyError: 'datetime64[ns]'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
Cell In[12], line 1
----> 1 pt.as_tensor(index)

File .venv/lib/python3.10/site-packages/pytensor/tensor/__init__.py:49, in as_tensor_variable(x, name, ndim, **kwargs)
     17 def as_tensor_variable(
     18     x: TensorLike, name: Optional[str] = None, ndim: Optional[int] = None, **kwargs
     19 ) -> "TensorVariable":
     20     """Convert `x` into an equivalent `TensorVariable`.
     21 
     22     This function can be used to turn ndarrays, numbers, `ScalarType` instances,
   (...)
     47 
     48     """
---> 49     return _as_tensor_variable(x, name, ndim, **kwargs)

File /usr/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File .venv/lib/python3.10/site-packages/pytensor/tensor/basic.py:176, in _as_tensor_numbers(x, name, ndim, dtype, **kwargs)
    171 @_as_tensor_variable.register(np.bool_)
    172 @_as_tensor_variable.register(np.number)
    173 @_as_tensor_variable.register(Number)
    174 @_as_tensor_variable.register(np.ndarray)
    175 def _as_tensor_numbers(x, name, ndim, dtype=None, **kwargs):
--> 176     return constant(x, name=name, ndim=ndim, dtype=dtype)

File venv/lib/python3.10/site-packages/pytensor/tensor/basic.py:229, in constant(x, name, ndim, dtype)
    223             raise ValueError(
    224                 f"ndarray could not be cast to constant with {int(ndim)} dimensions"
    225             )
    227     assert x_.ndim == ndim
--> 229 ttype = TensorType(dtype=x_.dtype, shape=x_.shape)
    231 return TensorConstant(ttype, x_, name=name)

File .venv/lib/python3.10/site-packages/pytensor/tensor/type.py:116, in TensorType.__init__(self, dtype, shape, name, broadcastable)
    113         return s
    115 self.shape = tuple(parse_bcast_and_shape(s) for s in shape)
--> 116 self.dtype_specs()  # error checking is done there
    117 self.name = name
    118 self.numpy_dtype = np.dtype(self.dtype)

File .venv/lib/python3.10/site-packages/pytensor/tensor/type.py:289, in TensorType.dtype_specs(self)
    287     return self.dtype_specs_map[self.dtype]
    288 except KeyError:
--> 289     raise TypeError(
    290         f"Unsupported dtype for {self.__class__.__name__}: {self.dtype}"
    291     )

TypeError: Unsupported dtype for TensorType: datetime64[ns]

After

No error

Context for the issue:

Would be nice to have native support for datetimes in pytensor

ferrine avatar Sep 12 '23 14:09 ferrine

What is the case for supporting this? Do you want to do operations on time variables? That's fine but a considerable effort akin to #259

ricardoV94 avatar Sep 12 '23 15:09 ricardoV94

Bumping this because I'm working on a project where I want to do operations on time variables.

Specifically, I want to be able to take inputs of the form {start_date, end_date, frequency, payment_frequency, payment} and get a symbolic vector with either zero if a payment occurs in a period else payment.

jessegrabowski avatar Jul 10 '25 02:07 jessegrabowski

As with every type you need to think how to support seamlessly in different backends and what sorts of operations you want.

And whether those are better addressed as syntactic sugar to regular tensor operations

ricardoV94 avatar Jul 10 '25 05:07 ricardoV94