-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Vectorized lazy indexing #1899
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
Vectorized lazy indexing #1899
Changes from 33 commits
dceb298
c1b4b60
d989a15
218763c
541fca3
3e05a16
030a2c4
b9f97b4
850f29c
943ec78
91aae64
991c1da
936954a
9144965
d1cb976
95e1f1c
180c4f5
dbbe531
c2e61ad
b545c3e
872de73
bb5d1f6
cfe29bb
17a7dac
2dff278
ead6327
a90ac05
73f4958
fd04966
b3c3d80
259f36c
0e7eb2e
0c2e31b
d8421a5
7e0959c
4fccdee
8e96710
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,48 +42,73 @@ def dtype(self): | |
def shape(self): | ||
return self._shape | ||
|
||
def __getitem__(self, key): | ||
key = indexing.unwrap_explicit_indexer( | ||
key, self, allow=(indexing.BasicIndexer, indexing.OuterIndexer)) | ||
def _get_indexer(self, key): | ||
""" Get indexer for rasterio array. | ||
|
||
Parameter | ||
--------- | ||
key: ExplicitIndexer | ||
|
||
Returns | ||
------- | ||
band_key: an indexer for the 1st dimension | ||
window: two tuples. Each consists of (start, stop). | ||
squeeze_axis: axes to be squeezed | ||
np_ind: indexer for loaded numpy array | ||
|
||
See also | ||
-------- | ||
indexing.decompose_indexer | ||
""" | ||
key, np_inds = indexing.decompose_indexer( | ||
key, self.shape, indexing.IndexingSupport.OUTER) | ||
|
||
# bands cannot be windowed but they can be listed | ||
band_key = key[0] | ||
n_bands = self.shape[0] | ||
band_key = key.tuple[0] | ||
new_shape = [] | ||
np_inds2 = [] | ||
# bands (axis=0) cannot be windowed but they can be listed | ||
if isinstance(band_key, slice): | ||
start, stop, step = band_key.indices(n_bands) | ||
if step is not None and step != 1: | ||
raise IndexError(_ERROR_MSG) | ||
band_key = np.arange(start, stop) | ||
start, stop, step = band_key.indices(self.shape[0]) | ||
band_key = np.arange(start, stop, step) | ||
# be sure we give out a list | ||
band_key = (np.asarray(band_key) + 1).tolist() | ||
if isinstance(band_key, list): # if band_key is not a scalar | ||
new_shape.append(len(band_key)) | ||
np_inds2.append(slice(None)) | ||
|
||
# but other dims can only be windowed | ||
window = [] | ||
squeeze_axis = [] | ||
for i, (k, n) in enumerate(zip(key[1:], self.shape[1:])): | ||
for i, (k, n) in enumerate(zip(key.tuple[1:], self.shape[1:])): | ||
if isinstance(k, slice): | ||
# step is always positive. see indexing.decompose_indexer | ||
start, stop, step = k.indices(n) | ||
if step is not None and step != 1: | ||
raise IndexError(_ERROR_MSG) | ||
np_inds2.append(slice(None, None, step)) | ||
new_shape.append(stop - start) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this needs logic to handle negative There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. I completely forgot about the negative step. |
||
elif is_scalar(k): | ||
# windowed operations will always return an array | ||
# we will have to squeeze it later | ||
squeeze_axis.append(i + 1) | ||
squeeze_axis.append(- (2 - i)) | ||
start = k | ||
stop = k + 1 | ||
else: | ||
k = np.asarray(k) | ||
start = k[0] | ||
stop = k[-1] + 1 | ||
ids = np.arange(start, stop) | ||
if not ((k.shape == ids.shape) and np.all(k == ids)): | ||
raise IndexError(_ERROR_MSG) | ||
start, stop = np.min(k), np.max(k) + 1 | ||
np_inds2.append(k - start) | ||
new_shape.append(stop - start) | ||
window.append((start, stop)) | ||
|
||
np_inds = indexing._combine_indexers( | ||
indexing.OuterIndexer(tuple(np_inds2)), new_shape, np_inds) | ||
return band_key, window, tuple(squeeze_axis), np_inds | ||
|
||
def __getitem__(self, key): | ||
band_key, window, squeeze_axis, np_inds = self._get_indexer(key) | ||
|
||
out = self.rasterio_ds.read(band_key, window=tuple(window)) | ||
if squeeze_axis: | ||
out = np.squeeze(out, axis=squeeze_axis) | ||
return out | ||
return indexing.NumpyIndexingAdapter(out)[np_inds] | ||
|
||
|
||
def _parse_envi(meta): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah-hah! I see the bug!
key
never gets used!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this should probably be something like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the debugging this!!
We certainly need test coverage for this.