Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: '_ElementwiseFunctionArray' object does not support item assignment #6015

Open
tomvothecoder opened this issue Nov 22, 2021 · 4 comments

Comments

@tomvothecoder
Copy link
Contributor

tomvothecoder commented Nov 22, 2021

What happened:
I am attempting to mask specific time_bnds coordinate points using loc, but am receiving TypeError: '_ElementwiseFunctionArray' object does not support item assignment.

This happens with datasets that have encoded (raw) time coordinates, then decoding with xr.decode_cf() before attempting to mask the time_bnds.

What you expected to happen:

The time_bnds coordinate points selected using .loc should mask properly

Minimal Complete Verifiable Example:

MVCE 1 -- breaks with encoded time coordinates then decoded using xr.decode_cf()

import numpy as np
import xarray as xr

time_encoded = xr.DataArray(
    name="time",
    data=[675348.5, 675378.0, 675407.5],
    dims=["time"],
    attrs={
        "bounds": "time_bnds",
        "units": "days since 0001-01-01",
        "calendar": "proleptic_gregorian",
        "axis": "T",
        "long_name": "time",
        "standard_name": "time",
    },
)
time_bnds_encoded = xr.DataArray(
    name="time_bnds",
    data=[[675333.0, 675364.0], [675364.0, 675392.0], [675392.0, 675423.0]],
    dims=["time", "bnds"],
)

ds = xr.Dataset(
    coords={"time": time_encoded}, data_vars={"time_bnds": time_bnds_encoded}
)
ds = xr.decode_cf(ds, decode_times=True)
ds["time_bnds"].loc[dict(time="1850-01")] = np.nan

MVCE 2 -- works fine with decoded time coordinates

import cftime
import numpy as np
import xarray as xr

time_decoded = xr.DataArray(
    name="time",
    data=np.array(
        [
            cftime.DatetimeProlepticGregorian(
                1850, 1, 16, 12, 0, 0, 0, has_year_zero=True
            ),
            cftime.DatetimeProlepticGregorian(
                1850, 2, 15, 0, 0, 0, 0, has_year_zero=True
            ),
            cftime.DatetimeProlepticGregorian(
                1850, 3, 16, 12, 0, 0, 0, has_year_zero=True
            ),
        ],
        dtype="object",
    ),
    dims=["time"],
    attrs={
        "bounds": "time_bnds",
        "axis": "T",
        "long_name": "time",
        "standard_name": "time",
    },
)
time_decoded.encoding = {
    "units": "days since 0001-01-01",
    "calendar": "proleptic_gregorian",
}
time_bnds_decoded = xr.DataArray(
    dims=["time", "bnds"],
    data=[
        [np.nan, np.nan],
        [
            cftime.DatetimeProlepticGregorian(
                1850, 2, 1, 0, 0, 0, 0, has_year_zero=True
            ),
            cftime.DatetimeProlepticGregorian(
                1850, 3, 1, 0, 0, 0, 0, has_year_zero=True
            ),
        ],
        [
            cftime.DatetimeProlepticGregorian(
                1850, 3, 1, 0, 0, 0, 0, has_year_zero=True
            ),
            cftime.DatetimeProlepticGregorian(
                1850, 4, 1, 0, 0, 0, 0, has_year_zero=True
            ),
        ],
    ],
)

ds = xr.Dataset(
    coords={"time": time_decoded}, data_vars={"time_bnds": time_bnds_decoded}
)
ds["time_bnds"].loc[dict(time="1850-01")] = np.nan

Anything else we need to know?:

The workaround is to perform .load() after xr.decode_cf()

import numpy as np
import xarray as xr

time_encoded = xr.DataArray(
    name="time",
    data=[675348.5, 675378.0, 675407.5],
    dims=["time"],
    attrs={
        "bounds": "time_bnds",
        "units": "days since 0001-01-01",
        "calendar": "proleptic_gregorian",
        "axis": "T",
        "long_name": "time",
        "standard_name": "time",
    },
)
time_bnds_encoded = xr.DataArray(
    name="time_bnds",
    data=[[675333.0, 675364.0], [675364.0, 675392.0], [675392.0, 675423.0]],
    dims=["time", "bnds"],
)

ds = xr.Dataset(
    coords={"time": time_encoded}, data_vars={"time_bnds": time_bnds_encoded}
)
ds = xr.decode_cf(ds, decode_times=True)
ds.load()
ds["time_bnds"].loc[dict(time="1850-01")] = np.nan

Log Output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File /Users/vo13/repositories/xcdat/qa/xr_6015.py:27
     [23](https://file+.vscode-resource.vscode-cdn.net/Users/vo13/repositories/xcdat/qa/xr_6015.py:23) ds = xr.Dataset(
     [24](https://file+.vscode-resource.vscode-cdn.net/Users/vo13/repositories/xcdat/qa/xr_6015.py:24)     coords={"time": time_encoded}, data_vars={"time_bnds": time_bnds_encoded}
     [25](https://file+.vscode-resource.vscode-cdn.net/Users/vo13/repositories/xcdat/qa/xr_6015.py:25) )
     [26](https://file+.vscode-resource.vscode-cdn.net/Users/vo13/repositories/xcdat/qa/xr_6015.py:26) ds = xr.decode_cf(ds, decode_times=True)
---> [27](https://file+.vscode-resource.vscode-cdn.net/Users/vo13/repositories/xcdat/qa/xr_6015.py:27) ds["time_bnds"].loc[dict(time="1850-01")] = np.nan

File /opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:246, in _LocIndexer.__setitem__(self, key, value)
    [243](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:243)     key = dict(zip(self.data_array.dims, labels))
    [245](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:245) dim_indexers = map_index_queries(self.data_array, key).dim_indexers
--> [246](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:246) self.data_array[dim_indexers] = value

File /opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:892, in DataArray.__setitem__(self, key, value)
    [887](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:887) # DataArray key -> Variable key
    [888](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:888) key = {
    [889](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:889)     k: v.variable if isinstance(v, DataArray) else v
    [890](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:890)     for k, v in self._item_key_to_dict(key).items()
    [891](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:891) }
--> [892](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/dataarray.py:892) self.variable[key] = value

File /opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/variable.py:866, in Variable.__setitem__(self, key, value)
    [863](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/variable.py:863)     value = np.moveaxis(value, new_order, range(len(new_order)))
    [865](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/variable.py:865) indexable = as_indexable(self._data)
--> [866](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/variable.py:866) indexing.set_with_indexer(indexable, index_tuple, value)

File /opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:1012, in set_with_indexer(indexable, indexer, value)
   [1010](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:1010)     indexable.oindex[indexer] = value
   [1011](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:1011) else:
-> [1012](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:1012)     indexable[indexer] = value

File /opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:660, in LazilyIndexedArray.__setitem__(self, key, value)
    [658](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:658) self._check_and_raise_if_non_basic_indexer(key)
    [659](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:659) full_key = self._updated_key(key)
--> [660](https://file+.vscode-resource.vscode-cdn.net/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/xarray/core/indexing.py:660) self.array[full_key] = value

TypeError: '_ElementwiseFunctionArray' object does not support item assignment

Environment:

Output of xr.show_versions()

INSTALLED VERSIONS

commit: None
python: 3.11.9 | packaged by conda-forge | (main, Apr 19 2024, 18:34:54) [Clang 16.0.6 ]
python-bits: 64
OS: Darwin
OS-release: 22.6.0
machine: arm64
processor: arm
byteorder: little
LC_ALL: None
LANG: None
LOCALE: (None, 'UTF-8')
libhdf5: 1.14.3
libnetcdf: 4.9.2

xarray: 2024.3.0
pandas: 2.2.2
numpy: 1.26.4
scipy: 1.13.0
netCDF4: 1.6.5
pydap: None
h5netcdf: None
h5py: None
Nio: None
zarr: None
cftime: 1.6.3
nc_time_axis: 1.4.1
iris: None
bottleneck: None
dask: 2024.4.2
distributed: 2024.4.2
matplotlib: 3.8.4
cartopy: None
seaborn: None
numbagg: None
fsspec: 2024.3.1
cupy: None
pint: None
sparse: 0.15.1
flox: None
numpy_groupies: None
setuptools: 69.5.1
pip: 24.0
conda: None
pytest: 8.2.0
mypy: 1.4.0
IPython: 8.22.2
sphinx: 7.3.7
/opt/miniconda3/envs/xcdat_dev/lib/python3.11/site-packages/_distutils_hack/init.py:26: UserWarning: Setuptools is replacing distutils.
warnings.warn("Setuptools is replacing distutils.")

@max-sixty max-sixty added the needs mcve https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports label Aug 28, 2024
@max-sixty
Copy link
Collaborator

Sorry this didn't get traction. Could we adjust the example to be an MCVE?

@tomvothecoder
Copy link
Contributor Author

@max-sixty Sure I can add an MCVE soon

@tomvothecoder
Copy link
Contributor Author

tomvothecoder commented Aug 28, 2024

Description has been updated with an MVCE and up-to-date details

@max-sixty
Copy link
Collaborator

Thank you! Repro-ed...

@max-sixty max-sixty added bug topic-backends and removed needs mcve https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports labels Aug 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants