Skip to content

Request for fancy indexing #657

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

Closed
AbigailMcGovern opened this issue Nov 24, 2020 · 11 comments
Closed

Request for fancy indexing #657

AbigailMcGovern opened this issue Nov 24, 2020 · 11 comments

Comments

@AbigailMcGovern
Copy link

Overview

Attempting to modify/retrive values in a zarr array with fancy indexing results in an error.

Minimal, reproducible code sample

For instance, a tuple of list indices

import zarr
array  = zarr.zeros((20, 20))
array[[1, 2, 3], [1, 2, 3]] = 1

Results in the following:

IndexError: unsupported selection item for basic indexing; expected integer or slice, got <class 'list'>

However, this works usingvindex

array.vindex[[1, 2, 3], [1, 2, 3]] = 1
print(array.vindex[[1, 2, 3], [1, 2, 3]])
# Output: [1. 1. 1.]

Problem description

Zarr's Array class does not support fancy indexing via the standard numpy-like syntax, which causes issues when attempting to write to zarr arrays via napari's label layer. These problems arise because several of the label editing tools in napari (e.g., paintbrush, fill tool, etc) require fancy indexing. @jni and myself are hoping that the logic in vindex can be incorporated to Array's __setitem__ and __getitem__. Any advice you can offer in this regard would be much appreciated!

Version and installation information

  • zarr.__version__ --> 2.4.0
  • numcodecs.__version__ --> 0.7.2
  • Version of Python interpreter --> 3.8.5
  • Operating system --> Mac
  • How Zarr was installed --> conda
@jakirkham
Copy link
Member

Advanced indexing is covered in these docs.

That said, we wound up not adding these to __getitem__ and __setitem__ as folks found this syntax a bit confusing to parse and distinguish from the different types of fancy indexing. Instead we added custom methods or vindex and oindex for clarity, which seems to follow Dask, a NEP, and some other projects that have gone down this road. For more context this functionality was added in PR ( #172 ).

@jni
Copy link
Contributor

jni commented Nov 24, 2020

Thanks @jakirkham!

Instead we added custom methods or vindex and oindex for clarity, which seems to follow Dask, a NEP, and some other projects that have gone down this road

The problem is that NumPy itself has not, at least not yet, so in order for napari to support this we would have to implement different code for different array libraries. Fancy indexing is standard NumPy behaviour and it seems to me that, since it's already implemented, it should be straightforward to detect whether a tuple of arrays is given, and do .vindex in that case?

Note: I do think the case of mixing slices and arrays is confusing, but that implementation could be skipped for now? ie one can strictly increase the number of supported use cases without having to implement a whole stack of new functionality?

@jakirkham
Copy link
Member

@zarr-developers/core-devs, would be good to hear from people on whether this change sounds reasonable

@shoyer
Copy link
Contributor

shoyer commented Mar 3, 2021 via email

@rabernat
Copy link
Contributor

rabernat commented Mar 3, 2021

Would this constitute a breaking change? Or just something that used to error that now would work? If the latter, I am 👍. People don't have to use it if they find it confusing!

@jakirkham
Copy link
Member

I think it currently errors

@jakirkham
Copy link
Member

For context this came up as it is handy in duck-typed code that may handle many NumPy-like things (like Dask, Zarr, etc.).

@shoyer
Copy link
Contributor

shoyer commented Mar 3, 2021

For context this came up as it is handy in duck-typed code that may handle many NumPy-like things (like Dask, Zarr, etc.).

To be clear, Dask is not yet current consistent with NumPy, either, but that could be fixed: dask/dask#7313. Thus I would advise caution before relying on this feature :)

@jakirkham
Copy link
Member

^ @jni

@jni
Copy link
Contributor

jni commented Mar 3, 2021

We're ok, we don't do the crazy combining stuff. 😜 I think! 😅

Thanks @shoyer, we'll try to submit a PR soon!

jni added a commit to jni/zarr-python that referenced this issue Apr 28, 2021
Addresses zarr-developers#657

This matches NumPy behaviour in that basic, boolean, and vectorized
integer (fancy) indexing are all accessible from `__{get,set}item__`.
Users still have access to all the indexing methods if they want to be
sure to use only basic indexing (integer + slices).
jni added a commit to jni/zarr-python that referenced this issue May 4, 2021
Addresses zarr-developers#657

This matches NumPy behaviour in that basic, boolean, and vectorized
integer (fancy) indexing are all accessible from `__{get,set}item__`.
Users still have access to all the indexing methods if they want to be
sure to use only basic indexing (integer + slices).
jni added a commit to jni/zarr-python that referenced this issue May 18, 2021
Addresses zarr-developers#657

This matches NumPy behaviour in that basic, boolean, and vectorized
integer (fancy) indexing are all accessible from `__{get,set}item__`.
Users still have access to all the indexing methods if they want to be
sure to use only basic indexing (integer + slices).
jni added a commit to jni/zarr-python that referenced this issue May 31, 2021
Addresses zarr-developers#657

This matches NumPy behaviour in that basic, boolean, and vectorized
integer (fancy) indexing are all accessible from `__{get,set}item__`.
Users still have access to all the indexing methods if they want to be
sure to use only basic indexing (integer + slices).
jni added a commit to jni/zarr-python that referenced this issue Sep 29, 2021
Addresses zarr-developers#657

This matches NumPy behaviour in that basic, boolean, and vectorized
integer (fancy) indexing are all accessible from `__{get,set}item__`.
Users still have access to all the indexing methods if they want to be
sure to use only basic indexing (integer + slices).
joshmoore added a commit that referenced this issue Oct 19, 2021
* Fall back on .vindex when basic indexing fails

Addresses #657

This matches NumPy behaviour in that basic, boolean, and vectorized
integer (fancy) indexing are all accessible from `__{get,set}item__`.
Users still have access to all the indexing methods if they want to be
sure to use only basic indexing (integer + slices).

* Fix basic selection test now with no IndexError

* Fix basic_selection_2d test with no vindex error

* Add specific test for fancy indexing fallback

* Update get/setitem docstrings

* Update tutorial.rst

* PEP8 fix

* Rename test array to z as in other tests

* Add release note

* Avoid mixing slicing and array indexing in setitem

* Actually test for fancy index rather than try/except

* Add check for 1D fancy index (no tuple)

* Add tests for implicit fancy indexing, and getitem

* Add expected blank line

* Add strict test for make_slice_selection

* Ensure make_slice_selection returns valid NumPy slices

* Make pytest verbose to see what is failing in windows

* Add 5 min per-test timeout

* Use private self._shape when determining ndim

self.shape is a property that hides a lot of computation, and, more
importantly, it can be waiting for an update and so .ndim *cannot* be
accessed during a reshape/append. See:

#725 (comment)

This should prevent that behavior.

Co-authored-by: Josh Moore <[email protected]>
@jni
Copy link
Contributor

jni commented Oct 20, 2021

Closed by #725! 🎉

@jni jni closed this as completed Oct 20, 2021
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

No branches or pull requests

5 participants