Decompose vectorized indexer to the successive two indexers, where the first indexer will be used to index backend arrays, while the second one is used to index loaded on-memory np.ndarray. Parameters ---------- indexer : VectorizedIndexer indexing_support : one of Inde
(
indexer: VectorizedIndexer,
shape: _Shape,
indexing_support: IndexingSupport,
)
| 1235 | |
| 1236 | |
| 1237 | def _decompose_vectorized_indexer( |
| 1238 | indexer: VectorizedIndexer, |
| 1239 | shape: _Shape, |
| 1240 | indexing_support: IndexingSupport, |
| 1241 | ) -> tuple[ExplicitIndexer, ExplicitIndexer]: |
| 1242 | """ |
| 1243 | Decompose vectorized indexer to the successive two indexers, where the |
| 1244 | first indexer will be used to index backend arrays, while the second one |
| 1245 | is used to index loaded on-memory np.ndarray. |
| 1246 | |
| 1247 | Parameters |
| 1248 | ---------- |
| 1249 | indexer : VectorizedIndexer |
| 1250 | indexing_support : one of IndexerSupport entries |
| 1251 | |
| 1252 | Returns |
| 1253 | ------- |
| 1254 | backend_indexer: OuterIndexer or BasicIndexer |
| 1255 | np_indexers: an ExplicitIndexer (VectorizedIndexer / BasicIndexer) |
| 1256 | |
| 1257 | Notes |
| 1258 | ----- |
| 1259 | This function is used to realize the vectorized indexing for the backend |
| 1260 | arrays that only support basic or outer indexing. |
| 1261 | |
| 1262 | As an example, let us consider to index a few elements from a backend array |
| 1263 | with a vectorized indexer ([0, 3, 1], [2, 3, 2]). |
| 1264 | Even if the backend array only supports outer indexing, it is more |
| 1265 | efficient to load a subslice of the array than loading the entire array, |
| 1266 | |
| 1267 | >>> array = np.arange(36).reshape(6, 6) |
| 1268 | >>> backend_indexer = OuterIndexer((np.array([0, 1, 3]), np.array([2, 3]))) |
| 1269 | >>> # load subslice of the array |
| 1270 | ... array = NumpyIndexingAdapter(array).oindex[backend_indexer] |
| 1271 | >>> np_indexer = VectorizedIndexer((np.array([0, 2, 1]), np.array([0, 1, 0]))) |
| 1272 | >>> # vectorized indexing for on-memory np.ndarray. |
| 1273 | ... NumpyIndexingAdapter(array).vindex[np_indexer] |
| 1274 | array([ 2, 21, 8]) |
| 1275 | """ |
| 1276 | assert isinstance(indexer, VectorizedIndexer) |
| 1277 | |
| 1278 | if indexing_support is IndexingSupport.VECTORIZED: |
| 1279 | return indexer, BasicIndexer(()) |
| 1280 | |
| 1281 | backend_indexer_elems: list[slice | np.ndarray[Any, np.dtype[np.generic]]] = [] |
| 1282 | np_indexer_elems: list[slice | np.ndarray[Any, np.dtype[np.generic]]] = [] |
| 1283 | # convert negative indices |
| 1284 | indexer_elems = [ |
| 1285 | np.where(k < 0, k + s, k) if isinstance(k, np.ndarray) else k |
| 1286 | for k, s in zip(indexer.tuple, shape, strict=True) |
| 1287 | ] |
| 1288 | |
| 1289 | for k, s in zip(indexer_elems, shape, strict=True): |
| 1290 | if isinstance(k, slice): |
| 1291 | # If it is a slice, then we will slice it as-is |
| 1292 | # (but make its step positive) in the backend, |
| 1293 | # and then use all of it (slice(None)) for the in-memory portion. |
| 1294 | bk_slice, np_slice = _decompose_slice(k, s) |
no test coverage detected
searching dependent graphs…