ak.contents.BitMaskedArray#

Defined in awkward.contents.bitmaskedarray on line 53.

class ak.contents.BitMaskedArray(self, mask, content, valid_when, length, lsb_order, *, parameters=None)#

Like ak.contents.ByteMaskedArray, BitMaskedArray implements an ak.types.OptionType with two buffers, mask and content. However, the boolean mask values are packed into a bitmap.

BitMaskedArray has an additional parameter, lsb_order; if True, the position of each bit is in Least-Significant Bit order (LSB):

is_valid[j] = bool(mask[j // 8] & (1 << (j % 8))) == valid_when

If False, the position of each bit is in Most-Significant Bit order (MSB):

is_valid[j] = bool(mask[j // 8] & (128 >> (j % 8))) == valid_when

If the logical size of the buffer is not a multiple of 8, the mask has to be padded. Thus, an explicit length is also part of the class’s definition.

This is equivalent to all of Apache Arrow’s array types because they all use bitmaps to mask their data, with valid_when=True and lsb_order=True.

To illustrate how the constructor arguments are interpreted, the following is a simplified implementation of __init__, __len__, and __getitem__:

class BitMaskedArray(Content):
    def __init__(self, mask, content, valid_when, length, lsb_order):
        assert isinstance(mask, IndexU8)
        assert isinstance(content, Content)
        assert isinstance(valid_when, bool)
        assert isinstance(length, int) and length >= 0
        assert isinstance(lsb_order, bool)
        assert len(mask) <= len(content)
        self.mask = mask
        self.content = content
        self.valid_when = valid_when
        self.length = length
        self.lsb_order = lsb_order

    def __len__(self):
        return self.length

    def __getitem__(self, where):
        if isinstance(where, int):
            if where < 0:
                where += len(self)
            assert 0 <= where < len(self)
            if self.lsb_order:
                bit = bool(self.mask[where // 8] & (1 << (where % 8)))
            else:
                bit = bool(self.mask[where // 8] & (128 >> (where % 8)))
            if bit == self.valid_when:
                return self.content[where]
            else:
                return None

        elif isinstance(where, slice) and where.step is None:
            # In general, slices must convert BitMaskedArray to ByteMaskedArray.
            bytemask = np.unpackbits(
                self.mask, bitorder=("little" if self.lsb_order else "big")
            ).view(bool)
            return ByteMaskedArray(
                bytemask[where.start : where.stop],
                self.content[where.start : where.stop],
                valid_when=self.valid_when,
            )

        elif isinstance(where, str):
            return BitMaskedArray(
                self.mask,
                self.content[where],
                valid_when=self.valid_when,
                length=self.length,
                lsb_order=self.lsb_order,
            )

        else:
            raise AssertionError(where)
ak.contents.BitMaskedArray.mask#
ak.contents.BitMaskedArray.valid_when#
ak.contents.BitMaskedArray.lsb_order#
ak.contents.BitMaskedArray.copy(self, mask=UNSET, content=UNSET, valid_when=UNSET, length=UNSET, lsb_order=UNSET, *, parameters=UNSET)#
ak.contents.BitMaskedArray.__copy__(self)#
ak.contents.BitMaskedArray.__deepcopy__(self, memo)#
ak.contents.BitMaskedArray.simplified(cls, mask, content, valid_when, length, lsb_order, *, parameters=None)#
ak.contents.BitMaskedArray._form_with_key(self, getkey)#
ak.contents.BitMaskedArray._to_buffers(self, form, getkey, container, backend, byteorder)#
ak.contents.BitMaskedArray._to_typetracer(self, forget_length)#
ak.contents.BitMaskedArray._touch_data(self, recursive)#
ak.contents.BitMaskedArray._touch_shape(self, recursive)#
ak.contents.BitMaskedArray.length#
ak.contents.BitMaskedArray.__repr__(self)#
ak.contents.BitMaskedArray._repr(self, indent, pre, post)#
ak.contents.BitMaskedArray.to_IndexedOptionArray64(self)#
ak.contents.BitMaskedArray.to_ByteMaskedArray(self)#
ak.contents.BitMaskedArray.to_BitMaskedArray(self, valid_when, lsb_order)#
ak.contents.BitMaskedArray.mask_as_bool(self, valid_when=None)#
ak.contents.BitMaskedArray._getitem_nothing(self)#
ak.contents.BitMaskedArray._is_getitem_at_placeholder(self)#
ak.contents.BitMaskedArray._getitem_at(self, where)#
ak.contents.BitMaskedArray._getitem_range(self, start, stop)#
ak.contents.BitMaskedArray._getitem_field(self, where, only_fields=())#
ak.contents.BitMaskedArray._getitem_fields(self, where, only_fields=())#
ak.contents.BitMaskedArray._carry(self, carry, allow_lazy)#
ak.contents.BitMaskedArray._getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail)#
ak.contents.BitMaskedArray._getitem_next(self, head, tail, advanced)#
ak.contents.BitMaskedArray.project(self, mask=None)#
ak.contents.BitMaskedArray._offsets_and_flattened(self, axis, depth)#
ak.contents.BitMaskedArray._mergeable_next(self, other, mergebool)#
ak.contents.BitMaskedArray._reverse_merge(self, other)#
ak.contents.BitMaskedArray._mergemany(self, others)#
ak.contents.BitMaskedArray._fill_none(self, value)#
ak.contents.BitMaskedArray._local_index(self, axis, depth)#
ak.contents.BitMaskedArray._numbers_to_type(self, name, including_unknown)#
ak.contents.BitMaskedArray._is_unique(self, negaxis, starts, parents, outlength)#
ak.contents.BitMaskedArray._unique(self, negaxis, starts, parents, outlength)#
ak.contents.BitMaskedArray._argsort_next(self, negaxis, starts, shifts, parents, outlength, ascending, stable)#
ak.contents.BitMaskedArray._sort_next(self, negaxis, starts, parents, outlength, ascending, stable)#
ak.contents.BitMaskedArray._combinations(self, n, replacement, recordlookup, parameters, axis, depth)#
ak.contents.BitMaskedArray._reduce_next(self, reducer, negaxis, starts, shifts, parents, outlength, mask, keepdims, behavior)#
ak.contents.BitMaskedArray._validity_error(self, path)#
ak.contents.BitMaskedArray._nbytes_part(self)#
ak.contents.BitMaskedArray._pad_none(self, target, axis, depth, clip)#
ak.contents.BitMaskedArray._to_arrow(self, pyarrow, mask_node, validbytes, length, options)#
ak.contents.BitMaskedArray._to_cudf(self, cudf, mask, length)#
ak.contents.BitMaskedArray._to_backend_array(self, allow_missing, backend)#
ak.contents.BitMaskedArray._remove_structure(self, backend, options)#
ak.contents.BitMaskedArray._drop_none(self)#
ak.contents.BitMaskedArray._recursively_apply(self, action, depth, depth_context, lateral_context, options)#
ak.contents.BitMaskedArray.to_packed(self, recursive=True)#
ak.contents.BitMaskedArray._to_list(self, behavior, json_conversions)#
ak.contents.BitMaskedArray._to_backend(self, backend)#
ak.contents.BitMaskedArray._is_equal_to(self, other, index_dtype, numpyarray, all_parameters)#