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

Assignment #1519

Open
leezu opened this issue Aug 24, 2017 · 6 comments
Open

Assignment #1519

leezu opened this issue Aug 24, 2017 · 6 comments

Comments

@leezu
Copy link
Contributor

leezu commented Aug 24, 2017

Assignment of individual elements / subsets seems to be only partially supported, but I have not found clear documentation on it. After playing a bit around with xarray I believe the current support boils down to the following (I list some issues I see with the current documentation and how things seem to work).

DataSet

  • Change a element in a associated DataArray
    • ds.loc[selector_dict].NAME_OF_VARIABLE = -1 Doesn't work but at least throws an error (Use __setitem__ style assignment (e.g., ds['name'] = ...) instead to assign variables.)
    • ds.loc[selector_dict]["NAME_OF_VARIABLE"] = -1 Silently fails
    • Same goes for ds.sel

DataArray
(Can be obtained via ds['name'])

  • Using .sel (which is documented to return a new DataArray, so arguably it's expected not to work)
    • ds["NAME_OF_VARIABLE"].sel(**selector_dict) = -1 Invalid python syntax
    • ds["NAME_OF_VARIABLE"].sel(**selector_dict).values = -1 Silently fails
  • Using .loc
    • ds["NAME_OF_VARIABLE"].loc[selector_dict] = -1 works

Is this the recommended behaviour? Then I believe the wrong pattern of ds.loc[selector_dict]["NAME_OF_VARIABLE"] = -1 should be documented and ds[NAME_OF_VARIABLE].loc[selector_dict] = -1 instead suggested.

@klapo
Copy link

klapo commented Mar 26, 2020

I'm re-pinging this issue since I was just bitten by it (on version 0.15).

If creating an exception is time consuming could we instead have a disclaimer regarding this behavior to the documentation? Here's a basic working example that shows that it does silently fail:

# Basic working example of the silently failing indexing assignment
ds = xr.Dataset({'a': (('x'), np.arange(4)),
                             'b': (('x'), np.arange(4))
                            })
# Silently fails assignment
ds.loc[{'x': 1}]['a'] = 10
print(ds)

# Works as intended
ds['a'].loc[{'x': 1}] = 10
print(ds)

@keewis
Copy link
Collaborator

keewis commented Mar 26, 2020

it's not that it fails, the original dataset is just not updated:

In [2]: ds = xr.Dataset({ 
   ...:     "a": ("x", np.arange(4)), 
   ...:     "b": ("x", np.arange(4)), 
   ...: })

In [3]: selected = ds.loc[{"x": 1}]
   ...: selected["a"] = 10
   ...: ds, selected
Out[3]:
(<xarray.Dataset>
 Dimensions:  (x: 4)
 Dimensions without coordinates: x
 Data variables:
     a        (x) int64 0 1 2 3
     b        (x) int64 0 1 2 3,
 <xarray.Dataset>
 Dimensions:  ()
 Data variables:
     a        int64 10
     b        int64 1)

to make it work, use (note the [...])

In [7]: selected = ds.loc[{"x": 1}] 
   ...: selected["a"][...] = 10 
   ...: ds, selected
Out[7]: 
(<xarray.Dataset>
 Dimensions:  (x: 4)
 Dimensions without coordinates: x
 Data variables:
     a        (x) int64 0 10 2 3
     b        (x) int64 0 1 2 3,
 <xarray.Dataset>
 Dimensions:  ()
 Data variables:
     a        int64 10
     b        int64 1)

The difference is that without the extra [...] we don't modify the values but instead create a new variable (so something like ds["new_variable"] = ("x", [1, 3, 4, 5]))

Also note that while ds.a.sel(x=1) = 10 raises a SyntaxError, ds.a.sel(x=1)[...] = 10 or ds.sel(x=1).a[...] = 10 have exactly the same effect as their loc counterparts.

We probably should add an explanation and examples to the documentation (loc / sel and maybe the indexing page?)

@keewis
Copy link
Collaborator

keewis commented Mar 26, 2020

also, we can't really raise only for ds.loc[...][name] = -1 since for python that is the same as

intermediate_ds = ds.loc[...]
intermediate_ds[name] = -1

where the second line is something we explicitly want to support.

@keewis
Copy link
Collaborator

keewis commented Apr 9, 2020

since it came up in #3939, I played around with this, and it seems the obj.sel(x=1)[...] = 0 syntax only works for DataArray objects and when assigning a single value. Should we try to make it work the same way as loc?

@dcherian
Copy link
Contributor

dcherian commented Apr 9, 2020

How does this even work? 😱

@stale
Copy link

stale bot commented May 2, 2022

In order to maintain a list of currently relevant issues, we mark issues as stale after a period of inactivity

If this issue remains relevant, please comment here or remove the stale label; otherwise it will be marked as closed automatically

@stale stale bot added the stale label May 2, 2022
@dcherian dcherian removed the stale label May 2, 2022
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

5 participants