@@ -325,6 +325,21 @@ def as_integer_slice(value):
325
325
return slice (start , stop , step )
326
326
327
327
328
+ class IndexCallable :
329
+ """Provide getitem syntax for a callable object."""
330
+
331
+ __slots__ = ("func" ,)
332
+
333
+ def __init__ (self , func ):
334
+ self .func = func
335
+
336
+ def __getitem__ (self , key ):
337
+ return self .func (key )
338
+
339
+ def __setitem__ (self , key , value ):
340
+ raise NotImplementedError
341
+
342
+
328
343
class BasicIndexer (ExplicitIndexer ):
329
344
"""Tuple for basic indexing.
330
345
@@ -470,6 +485,13 @@ def __array__(self, dtype: np.typing.DTypeLike = None) -> np.ndarray:
470
485
# Note this is the base class for all lazy indexing classes
471
486
return np .asarray (self .get_duck_array (), dtype = dtype )
472
487
488
+ def _oindex_get (self , key ):
489
+ raise NotImplementedError ("This method should be overridden" )
490
+
491
+ @property
492
+ def oindex (self ):
493
+ return IndexCallable (self ._oindex_get )
494
+
473
495
474
496
class ImplicitToExplicitIndexingAdapter (NDArrayMixin ):
475
497
"""Wrap an array, converting tuples into the indicated explicit indexer."""
@@ -560,6 +582,9 @@ def get_duck_array(self):
560
582
def transpose (self , order ):
561
583
return LazilyVectorizedIndexedArray (self .array , self .key ).transpose (order )
562
584
585
+ def _oindex_get (self , indexer ):
586
+ return type (self )(self .array , self ._updated_key (indexer ))
587
+
563
588
def __getitem__ (self , indexer ):
564
589
if isinstance (indexer , VectorizedIndexer ):
565
590
array = LazilyVectorizedIndexedArray (self .array , self .key )
@@ -663,6 +688,9 @@ def _ensure_copied(self):
663
688
def get_duck_array (self ):
664
689
return self .array .get_duck_array ()
665
690
691
+ def _oindex_get (self , key ):
692
+ return type (self )(_wrap_numpy_scalars (self .array [key ]))
693
+
666
694
def __getitem__ (self , key ):
667
695
return type (self )(_wrap_numpy_scalars (self .array [key ]))
668
696
@@ -696,6 +724,9 @@ def get_duck_array(self):
696
724
self ._ensure_cached ()
697
725
return self .array .get_duck_array ()
698
726
727
+ def _oindex_get (self , key ):
728
+ return type (self )(_wrap_numpy_scalars (self .array [key ]))
729
+
699
730
def __getitem__ (self , key ):
700
731
return type (self )(_wrap_numpy_scalars (self .array [key ]))
701
732
@@ -1332,6 +1363,10 @@ def _indexing_array_and_key(self, key):
1332
1363
def transpose (self , order ):
1333
1364
return self .array .transpose (order )
1334
1365
1366
+ def _oindex_get (self , key ):
1367
+ array , key = self ._indexing_array_and_key (key )
1368
+ return array [key ]
1369
+
1335
1370
def __getitem__ (self , key ):
1336
1371
array , key = self ._indexing_array_and_key (key )
1337
1372
return array [key ]
@@ -1376,16 +1411,19 @@ def __init__(self, array):
1376
1411
)
1377
1412
self .array = array
1378
1413
1414
+ def _oindex_get (self , key ):
1415
+ # manual orthogonal indexing (implemented like DaskIndexingAdapter)
1416
+ key = key .tuple
1417
+ value = self .array
1418
+ for axis , subkey in reversed (list (enumerate (key ))):
1419
+ value = value [(slice (None ),) * axis + (subkey , Ellipsis )]
1420
+ return value
1421
+
1379
1422
def __getitem__ (self , key ):
1380
1423
if isinstance (key , BasicIndexer ):
1381
1424
return self .array [key .tuple ]
1382
1425
elif isinstance (key , OuterIndexer ):
1383
- # manual orthogonal indexing (implemented like DaskIndexingAdapter)
1384
- key = key .tuple
1385
- value = self .array
1386
- for axis , subkey in reversed (list (enumerate (key ))):
1387
- value = value [(slice (None ),) * axis + (subkey , Ellipsis )]
1388
- return value
1426
+ return self .oindex [key ]
1389
1427
else :
1390
1428
if isinstance (key , VectorizedIndexer ):
1391
1429
raise TypeError ("Vectorized indexing is not supported" )
@@ -1395,11 +1433,10 @@ def __getitem__(self, key):
1395
1433
def __setitem__ (self , key , value ):
1396
1434
if isinstance (key , (BasicIndexer , OuterIndexer )):
1397
1435
self .array [key .tuple ] = value
1436
+ elif isinstance (key , VectorizedIndexer ):
1437
+ raise TypeError ("Vectorized indexing is not supported" )
1398
1438
else :
1399
- if isinstance (key , VectorizedIndexer ):
1400
- raise TypeError ("Vectorized indexing is not supported" )
1401
- else :
1402
- raise TypeError (f"Unrecognized indexer: { key } " )
1439
+ raise TypeError (f"Unrecognized indexer: { key } " )
1403
1440
1404
1441
def transpose (self , order ):
1405
1442
xp = self .array .__array_namespace__ ()
@@ -1417,24 +1454,25 @@ def __init__(self, array):
1417
1454
"""
1418
1455
self .array = array
1419
1456
1420
- def __getitem__ (self , key ):
1457
+ def _oindex_get (self , key ):
1458
+ key = key .tuple
1459
+ try :
1460
+ return self .array [key ]
1461
+ except NotImplementedError :
1462
+ # manual orthogonal indexing
1463
+ value = self .array
1464
+ for axis , subkey in reversed (list (enumerate (key ))):
1465
+ value = value [(slice (None ),) * axis + (subkey ,)]
1466
+ return value
1421
1467
1468
+ def __getitem__ (self , key ):
1422
1469
if isinstance (key , BasicIndexer ):
1423
1470
return self .array [key .tuple ]
1424
1471
elif isinstance (key , VectorizedIndexer ):
1425
1472
return self .array .vindex [key .tuple ]
1426
1473
else :
1427
1474
assert isinstance (key , OuterIndexer )
1428
- key = key .tuple
1429
- try :
1430
- return self .array [key ]
1431
- except NotImplementedError :
1432
- # manual orthogonal indexing.
1433
- # TODO: port this upstream into dask in a saner way.
1434
- value = self .array
1435
- for axis , subkey in reversed (list (enumerate (key ))):
1436
- value = value [(slice (None ),) * axis + (subkey ,)]
1437
- return value
1475
+ return self .oindex [key ]
1438
1476
1439
1477
def __setitem__ (self , key , value ):
1440
1478
if isinstance (key , BasicIndexer ):
@@ -1510,6 +1548,9 @@ def _convert_scalar(self, item):
1510
1548
# a NumPy array.
1511
1549
return to_0d_array (item )
1512
1550
1551
+ def _oindex_get (self , key ):
1552
+ return self .__getitem__ (key )
1553
+
1513
1554
def __getitem__ (
1514
1555
self , indexer
1515
1556
) -> (
0 commit comments