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

update_attrs method #1281

Closed
hsharrison opened this issue Feb 22, 2017 · 6 comments · Fixed by #1286
Closed

update_attrs method #1281

hsharrison opened this issue Feb 22, 2017 · 6 comments · Fixed by #1286

Comments

@hsharrison
Copy link
Contributor

hsharrison commented Feb 22, 2017

Updating attrs is an operation that consistently breaks up my method chaining. This should be easy to solve with something like

def update_attrs(self, *args, **kwargs):
    self.attrs.update(*args, **kwargs)
    return self

Thoughts?

edit: I guess it should return a modified object rather than acting as an in-place operation...is copying appropriate here? How is this usually handled?

@cwerner
Copy link

cwerner commented Feb 22, 2017

I would like something like this as well!
Also, specifying default attrs for all data arrays of a dataset (like missing_data/ _FillValue/ ...) would be nice... Not sure if this is currently possible?

@shoyer
Copy link
Member

shoyer commented Feb 23, 2017

edit: I guess it should return a modified object rather than acting as an in-place operation...is copying appropriate here? How is this usually handled?

The standard thing to do would be to do a shallow copy of the original object (which copies everything except array data) and then update attrs inplace, e.g.,

def update_attrs(self, *args, **kwargs):
    out = self.copy(deep=False)
    out.attrs.update(*args, **kwargs)
    return out

I like this idea, though I would call it assign_attrs rather than update_coords, to mirror assign and assign_coords.

I encourage you to get started on a pull request!

Also, specifying default attrs for all data arrays of a dataset (like missing_data/ _FillValue/ ...) would be nice... Not sure if this is currently possible?

I don't think there's any way to do this currently without a loop. I would say we're open to proposals, which you should probably open another issue to discuss :).

@hsharrison
Copy link
Contributor Author

Thanks for the tip. I'll give it a shot.

@max-sixty
Copy link
Collaborator

Thanks for the PR @hsharrison

Do ppl think the cost of an extra method is worth the cleaner syntax? Would ds.pipe(lambda x: x.attrs.update(foo=bar') suffice? It's easier to add methods than to remove them, though this approach does look nicer.

If python had a cleaner lambda...

@hsharrison
Copy link
Contributor Author

FWIW I've been doing

def update_attrs(obj, *args, **kwargs):
    obj.attrs.update(*args, **kwargs)
    return obj

ds.pipe(update_attrs, foo='bar')

which, yeah, is not too painful. But when I find myself using it every time I use xarray it makes me wish it was included.

A lambda solution is more difficult (maybe impossible?) because you need to update the attrs and return the original object to continue the pipe.

@max-sixty
Copy link
Collaborator

A lambda solution is more difficult (maybe impossible?) because you need to update the attrs and return the original object to continue the pipe.

Right, yes. Then there's no reasonable solution without this addition, I think

spencerkclark added a commit to ai2cm/fv3gfs-fortran that referenced this issue Jun 21, 2022
See the comment here for more information:
pydata/xarray#1281 (comment)
spencerkclark added a commit to ai2cm/fv3gfs-fortran that referenced this issue Jun 21, 2022
See the comment here for more information:
pydata/xarray#1281 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants