home / github / issues

Menu
  • Search all tables
  • GraphQL API

issues: 1833827348

This data as json

id node_id number title user state locked assignee milestone comments created_at updated_at closed_at author_association active_lock_reason draft pull_request body reactions performed_via_github_app state_reason repo type
1833827348 I_kwDOAMm_X85tTfwU 8045 CFTimeIndex does not work with nonstandard calendars with more than three dates 40894751 closed 0     3 2023-08-02T19:59:57Z 2023-10-12T18:16:39Z 2023-08-02T21:07:43Z NONE      

What happened?

I tried to wrap a xr.CFTimeIndex around a list of cftime 'noleap' datetime objects, but received a TypeError: cannot compute the time difference between dates with different calendars. This happens despite the fact that the dates are all from the same calendar:

```python import xarray as xr import cftime

This is fine

xr.CFTimeIndex([ cftime.datetime(2023, 7, 28, calendar='standard'), cftime.datetime(2023, 7, 29, calendar='standard'), cftime.datetime(2023, 7, 30, calendar='standard') ])

This raises TypeError

xr.CFTimeIndex([ cftime.datetime(2023, 7, 28, calendar='noleap'), cftime.datetime(2023, 7, 29, calendar='noleap'), cftime.datetime(2023, 7, 30, calendar='noleap') ]) ```

Some other things that I noticed: * xr.CFTimeIndex can wrap list of one or two non-standard calendar datetime objects. TypeError is only raised when three or more dates are used. ```python

This works

xr.CFTimeIndex([ cftime.datetime(2023, 7, 28, calendar='noleap'), cftime.datetime(2023, 7, 29, calendar='noleap') ]) ``` * xr.CFTimeIndex doesn't work on other non-standard calendars, such as "360_day" either.

I believe this should be possible, based on other xarray datasets loaded from netcdf that I've seen which include cftime indices for nonstandard calendars. But please let me know if I am using this incorrectly.

What did you expect to happen?

Returns cftimeindex: python xr.CFTimeIndex([2023-07-28 00:00:00, 2023-07-29 00:00:00, 2023-07-30 00:00:00], dtype='object', length=3, calendar='noleap', freq='D')

Minimal Complete Verifiable Example

```Python import numpy as np import xarray as xr import cftime

Lists of datetime objects

cftimes_standard = [ cftime.datetime(2023, 7, 28, calendar='standard'), cftime.datetime(2023, 7, 29, calendar='standard'), cftime.datetime(2023, 7, 30, calendar='standard') ]

cftimes_noleap = [ cftime.datetime(2023, 7, 28, calendar='noleap'), cftime.datetime(2023, 7, 29, calendar='noleap'), cftime.datetime(2023, 7, 30, calendar='noleap') ]

No problem with calling xr.CFTimeIndex on list of cftime.datetime standard calendars

xr.CFTimeIndex(cftimes_standard)

No problem with calling xr.CFTimeIndex on list of 2 cftime.datetime "noleap" objects

xr.CFTimeIndex(cftimes_noleap[0:2])

Problem with calling xr.CFTimeIndex on list of 3 cftime.datetime "noleap" objects

xr.CFTimeIndex(cftimes_noleap) ```

MVCE confirmation

  • [X] Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
  • [X] Complete example — the example is self-contained, including all data and the text of any traceback.
  • [X] Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
  • [X] New issue — a search of GitHub Issues suggests this is not a duplicate.

Relevant log output

```Python

TypeError Traceback (most recent call last) File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/IPython/core/formatters.py:708, in PlainTextFormatter.call(self, obj) 701 stream = StringIO() 702 printer = pretty.RepresentationPrinter(stream, self.verbose, 703 self.max_width, self.newline, 704 max_seq_length=self.max_seq_length, 705 singleton_pprinters=self.singleton_printers, 706 type_pprinters=self.type_printers, 707 deferred_pprinters=self.deferred_printers) --> 708 printer.pretty(obj) 709 printer.flush() 710 return stream.getvalue()

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/IPython/lib/pretty.py:410, in RepresentationPrinter.pretty(self, obj) 407 return meth(obj, self, cycle) 408 if cls is not object \ 409 and callable(cls.dict.get('repr')): --> 410 return _repr_pprint(obj, self, cycle) 412 return _default_pprint(obj, self, cycle) 413 finally:

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/IPython/lib/pretty.py:778, in repr_pprint(obj, p, cycle) 776 """A pprint that just redirects to the normal repr function.""" 777 # Find newlines and replace them with p.break() --> 778 output = repr(obj) 779 lines = output.splitlines() 780 with p.group():

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/coding/cftimeindex.py:356, in CFTimeIndex.repr(self) 348 end_str = format_times( 349 self.values[-REPR_ELLIPSIS_SHOW_ITEMS_FRONT_END:], 350 display_width, 351 offset=offset, 352 first_row_offset=offset, 353 ) 354 datastr = "\n".join([front_str, f"{' '*offset}...", end_str]) --> 356 attrs_str = format_attrs(self) 357 # oneliner only if smaller than display_width 358 full_repr_str = f"{klass_name}([{datastr}], {attrs_str})"

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/coding/cftimeindex.py:276, in format_attrs(index, separator) 270 def format_attrs(index, separator=", "): 271 """Format attributes of CFTimeIndex for repr.""" 272 attrs = { 273 "dtype": f"'{index.dtype}'", 274 "length": f"{len(index)}", 275 "calendar": f"'{index.calendar}'", --> 276 "freq": f"'{index.freq}'" if len(index) >= 3 else None, 277 } 279 attrs_str = [f"{k}={v}" for k, v in attrs.items()] 280 attrs_str = f"{separator}".join(attrs_str)

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/coding/cftimeindex.py:708, in CFTimeIndex.freq(self) 705 """The frequency used by the dates in the index.""" 706 from xarray.coding.frequencies import infer_freq --> 708 return infer_freq(self)

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/coding/frequencies.py:98, in infer_freq(index) 95 index = CFTimeIndex(index.values) 97 if isinstance(index, CFTimeIndex): ---> 98 inferer = _CFTimeFrequencyInferer(index) 99 return inferer.get_freq() 101 return pd.infer_freq(index)

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/coding/frequencies.py:107, in _CFTimeFrequencyInferer.init(self, index) 105 def init(self, index): 106 self.index = index --> 107 self.values = index.asi8 109 if len(index) < 3: 110 raise ValueError("Need at least 3 dates to infer frequency")

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/coding/cftimeindex.py:689, in CFTimeIndex.asi8(self) 685 from xarray.core.resample_cftime import exact_cftime_datetime_difference 687 epoch = self.date_type(1970, 1, 1) 688 return np.array( --> 689 [ 690 _total_microseconds(exact_cftime_datetime_difference(epoch, date)) 691 for date in self.values 692 ], 693 dtype=np.int64, 694 )

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/coding/cftimeindex.py:690, in <listcomp>(.0) 685 from xarray.core.resample_cftime import exact_cftime_datetime_difference 687 epoch = self.date_type(1970, 1, 1) 688 return np.array( 689 [ --> 690 _total_microseconds(exact_cftime_datetime_difference(epoch, date)) 691 for date in self.values 692 ], 693 dtype=np.int64, 694 )

File ~/miniforge3/envs/pangeo/lib/python3.9/site-packages/xarray/core/resample_cftime.py:495, in exact_cftime_datetime_difference(a, b) 461 def exact_cftime_datetime_difference(a: CFTimeDatetime, b: CFTimeDatetime): 462 """Exact computation of b - a 463 464 Assumes: (...) 493 datetime.timedelta 494 """ --> 495 seconds = b.replace(microsecond=0) - a.replace(microsecond=0) 496 seconds = int(round(seconds.total_seconds())) 497 microseconds = b.microsecond - a.microsecond

File src/cftime/_cftime.pyx:1574, in cftime._cftime.datetime.sub()

TypeError: cannot compute the time difference between dates with different calendars ```

Anything else we need to know?

No response

Environment

INSTALLED VERSIONS ------------------ commit: None python: 3.9.16 | packaged by conda-forge | (main, Feb 1 2023, 21:38:11) [Clang 14.0.6 ] python-bits: 64 OS: Darwin OS-release: 22.6.0 machine: arm64 processor: arm byteorder: little LC_ALL: None LANG: en_US.UTF-8 LOCALE: ('en_US', 'UTF-8') libhdf5: 1.14.1 libnetcdf: 4.9.2 xarray: 2023.7.0 pandas: 2.0.3 numpy: 1.24.4 scipy: 1.11.1 netCDF4: 1.6.4 pydap: None h5netcdf: None h5py: None Nio: None zarr: 2.16.0 cftime: 1.6.2 nc_time_axis: 1.4.1 PseudoNetCDF: None iris: None bottleneck: 1.3.7 dask: 2023.7.1 distributed: 2023.7.1 matplotlib: 3.7.2 cartopy: 0.21.1 seaborn: 0.12.2 numbagg: None fsspec: 2023.6.0 cupy: None pint: None sparse: None flox: None numpy_groupies: None setuptools: 68.0.0 pip: 23.2.1 conda: None pytest: None mypy: None IPython: 8.14.0 sphinx: None
{
    "url": "https://api.github.com/repos/pydata/xarray/issues/8045/reactions",
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
  completed 13221727 issue

Links from other tables

  • 2 rows from issues_id in issues_labels
  • 0 rows from issue in issue_comments
Powered by Datasette · Queries took 78.06ms · About: xarray-datasette