Repository navigation
add point slicing to dask.array.core - #439
Conversation
|
I think What happens if I index into a higher dimensional array? e.g., along two axes of a 3D array -- where does the new dimension go? This is assuredly the first thing that we'll try to do in xray :). |
|
That case is definitely not handled with the PR as is. Looks a bit tricker but doable. |
|
First, as @shoyer mentions - indexing a 3+d array with 2 indexers. The second takes that a bit further - how will we handle the case where we're indexing on the 1st and 3rd dims: # numpy syntax / behavior
>>> x = np.arange(60).reshape((5, 4, 3))
>>> x[[1, 2, 3], :, [1, 2, 2]]
array([[13, 16, 19, 22],
[26, 29, 32, 35],
[38, 41, 44, 47]])will |
|
Sorry to delay on this. This might require some thought and time which are in unfortunately short supply until next week. |
|
I just realized that because vectorized indexing (if slice objects are omitted) is equivalent to broadcasting, we can probably write the fully general form of vectorized indexing using import dask.array as da
import numpy as np
a = np.arange(25).reshape(5, 5)
x = da.from_array(a, chunks=3)
idx = da.from_array(np.arange(5), chunks=3)
da.core.elemwise(lambda *args: np.asarray(x)[args], idx, idx).compute()
# array([ 0, 6, 12, 18, 24]) |
|
On further consideration, vectorized indexing with |
This is equivalent to numpy slicing with multiple input lists. We could use a better name. cc @shoyer @jhamman Example ------- >>> x = np.arange(56).reshape((7, 8)) >>> x array([[ 0, 1, 2, 3, 4, 5, 6, 7], [ 8, 9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 30, 31], [32, 33, 34, 35, 36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47], [48, 49, 50, 51, 52, 53, 54, 55]]) >>> d = from_array(x, chunks=(3, 4)) >>> result = isel(d, [0, 1, 6, 0], [0, 1, 0, 7]) >>> result.compute() array([ 0, 9, 48, 7]) Fixes dask#433
|
OK. This seems to work. It was hard. I'll implement a |
In [1]: import dask.array as da
In [2]: import numpy as np
In [3]: x = np.arange(10*10*10).reshape((10, 10, 10))
In [4]: d = da.from_array(x, chunks=(4, 5, 6))
In [5]: d.vindex[[0, 5, 9], :, [0, 5, 9]]
Out[5]: dask.array<vindex-merge-2, shape=(3, 10), chunks=((3,), (5, 5)), dtype=int64>
In [6]: d.vindex[[0, 5, 9], :, [0, 5, 9]].compute()
Out[6]:
array([[ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90],
[505, 515, 525, 535, 545, 555, 565, 575, 585, 595],
[909, 919, 929, 939, 949, 959, 969, 979, 989, 999]])
In [7]: d.vindex[:, [0, 5, 9], [0, 5, 9]].compute()
Out[7]:
array([[ 0, 55, 99],
[100, 155, 199],
[200, 255, 299],
[300, 355, 399],
[400, 455, 499],
[500, 555, 599],
[600, 655, 699],
[700, 755, 799],
[800, 855, 899],
[900, 955, 999]]) |
|
The only qualm that I have with this PR is that the code is not particularly clear. Doing this properly was non-trivial and I do not envy the next person who has to come along (quite possibly also me). To this end further test cases are very welcome. Lets extend the amount of time until the next time someone needs to touch this. |
|
@jcrist points out that this doesn't yet support numpy arrays |
|
Fixed |
There was a problem hiding this comment.
to be clear: this will fail for multi-dimensional indexers, right? if so, we should catch that.
There was a problem hiding this comment.
We now raise on multi-dimensional indexers
In [1]: import dask.array as da
In [2]: import numpy as np
In [3]: x = np.arange(10*10*10).reshape((10, 10, 10))
In [4]: d = da.from_array(x, chunks=(4, 5, 6))
In [5]: d.vindex[[0, 5, 9], :, [0, 5, 9]]
Out[5]: dask.array<vindex-merge-2, shape=(3, 10), chunks=((3,), (5, 5)), dtype=int64>
In [6]: d.vindex[[0, 5, 9], :, [0, 5, 9]].compute()
Out[6]:
array([[ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90],
[505, 515, 525, 535, 545, 555, 565, 575, 585, 595],
[909, 919, 929, 939, 949, 959, 969, 979, 989, 999]])
In [7]: d.vindex[:, [0, 5, 9], [0, 5, 9]].compute()
Out[7]:
array([[ 0, 100, 200, 300, 400, 500, 600, 700, 800, 900],
[ 55, 155, 255, 355, 455, 555, 655, 755, 855, 955],
[ 99, 199, 299, 399, 499, 599, 699, 799, 899, 999]]) |
|
This example is broken: |
|
This should raise an exception, but doesn't: |
|
Fixed the two recent issues in two recent commits. |
|
Any further comments on this? |
|
@mrocklin - Thanks for putting this together. I just gave it a once over and the original use case seems to be well taken care of. |
|
Looks good to me |
|
Woot. Thanks for the detailed feedback all. |
add point slicing to dask.array.core
This is equivalent to numpy slicing with multiple input lists.
We could use a better name. cc @shoyer @jhamman
Example
Fixes #433