@@ -7,6 +7,7 @@ import numpy as np
7
7
8
8
cimport numpy as cnp
9
9
from cpython cimport PyErr_Clear
10
+ from cpython.slice cimport PySlice_Unpack
10
11
from libc.stdlib cimport (
11
12
free,
12
13
malloc,
@@ -468,13 +469,40 @@ cdef class BitmaskArray:
468
469
469
470
def __getitem__ (self , key ):
470
471
cdef Py_ssize_t ckey
472
+ cdef Py_ssize_t start, stop, step
473
+ cdef BitmaskArray bma
474
+ cdef ArrowBitmap bitmap
475
+ cdef int64_t nbytes
476
+ cdef BitmaskArray self_ = self
471
477
# to_numpy can be expensive, so try to avoid for simple cases
472
478
if isinstance (key, int ) and self .ndim == 1 :
473
479
ckey = key
474
480
if ckey >= 0 and ckey < self .bitmap.size_bits:
475
481
return bool (ArrowBitGet(self .bitmap.buffer.data, ckey))
476
482
elif is_null_slice(key):
477
483
return self .copy()
484
+ elif isinstance (key, slice ):
485
+ # fastpath for slices that start at 0 and step 1 at a time
486
+ # towards a positive number.
487
+ # TODO: upstream generic ArrowBitsGet function in nanoarrow
488
+ PySlice_Unpack(key, & start, & stop, & step)
489
+ if start == 0 and stop > 0 and step == 1 :
490
+ bma = BitmaskArray.__new__ (BitmaskArray)
491
+ ArrowBitmapInit(& bitmap)
492
+ nbytes = (stop + 7 ) // 8
493
+ ArrowBitmapReserve(& bitmap, nbytes)
494
+ memcpy(bitmap.buffer.data, self_.bitmap.buffer.data, nbytes)
495
+ bitmap.buffer.size_bytes = nbytes
496
+ bitmap.size_bits = stop
497
+
498
+ bma.bitmap = bitmap
499
+ bma.buffer_owner = True
500
+ bma.ndim = self_.ndim
501
+ bma.shape = self_.shape
502
+ bma.strides = self_.strides
503
+ bma.parent = False
504
+
505
+ return bma
478
506
479
507
return self .to_numpy()[key]
480
508
0 commit comments