Wrap an array to make basic and outer indexing lazy.
| 705 | |
| 706 | |
| 707 | class LazilyIndexedArray(ExplicitlyIndexedNDArrayMixin): |
| 708 | """Wrap an array to make basic and outer indexing lazy.""" |
| 709 | |
| 710 | __slots__ = ("_shape", "array", "key") |
| 711 | |
| 712 | def __init__(self, array: Any, key: ExplicitIndexer | None = None): |
| 713 | """ |
| 714 | Parameters |
| 715 | ---------- |
| 716 | array : array_like |
| 717 | Array like object to index. |
| 718 | key : ExplicitIndexer, optional |
| 719 | Array indexer. If provided, it is assumed to already be in |
| 720 | canonical expanded form. |
| 721 | """ |
| 722 | if isinstance(array, type(self)) and key is None: |
| 723 | # unwrap |
| 724 | key = array.key # type: ignore[has-type, unused-ignore] |
| 725 | array = array.array # type: ignore[has-type, unused-ignore] |
| 726 | |
| 727 | if key is None: |
| 728 | key = BasicIndexer((slice(None),) * array.ndim) |
| 729 | |
| 730 | self.array = as_indexable(array) |
| 731 | self.key = key |
| 732 | |
| 733 | shape: _Shape = () |
| 734 | for size, k in zip(self.array.shape, self.key.tuple, strict=True): |
| 735 | if isinstance(k, slice): |
| 736 | shape += (len(range(*k.indices(size))),) |
| 737 | elif isinstance(k, np.ndarray): |
| 738 | shape += (k.size,) |
| 739 | self._shape = shape |
| 740 | |
| 741 | def _updated_key(self, new_key: ExplicitIndexer) -> BasicIndexer | OuterIndexer: |
| 742 | iter_new_key = iter(expanded_indexer(new_key.tuple, self.ndim)) |
| 743 | |
| 744 | full_key: list[OuterIndexerType] = [] |
| 745 | for size, k in zip(self.array.shape, self.key.tuple, strict=True): |
| 746 | if isinstance(k, integer_types): |
| 747 | full_key.append(k) |
| 748 | else: |
| 749 | full_key.append(_index_indexer_1d(k, next(iter_new_key), size)) |
| 750 | full_key_tuple = tuple(full_key) |
| 751 | |
| 752 | if all(isinstance(k, integer_types + (slice,)) for k in full_key_tuple): |
| 753 | return BasicIndexer(cast(tuple[BasicIndexerType, ...], full_key_tuple)) |
| 754 | return OuterIndexer(full_key_tuple) |
| 755 | |
| 756 | @property |
| 757 | def shape(self) -> _Shape: |
| 758 | return self._shape |
| 759 | |
| 760 | def get_duck_array(self): |
| 761 | from xarray.backends.common import BackendArray |
| 762 | |
| 763 | if isinstance(self.array, BackendArray): |
| 764 | array = self.array[self.key] |
no outgoing calls
searching dependent graphs…