Esempio n. 1
0
    def to_index_level(
        self,
        offset: tp.Optional[int] = 0,
        cls: tp.Optional[tp.Type['IndexLevel']] = None,
    ) -> 'IndexLevel':
        '''
        A deepcopy with optional adjustments, such as a different offset and possibly a different class. The supplied class will be used to construct the IndexLevel instance (as well as internal indices), permitting the production of an IndexLevelGO.

        Args:
            offset: optionally provide a new offset for the copy. This is not applied recursively
        '''
        cls = cls if cls else self.__class__

        index = mutable_immutable_index_filter(cls.STATIC, self.index)

        if self.targets is not None:
            targets: tp.Optional[ArrayGO] = ArrayGO(
                [t.to_index_level(offset=None, cls=cls) for t in self.targets],
                own_iterable=True)
        else:
            targets = None

        offset = self.offset if offset is None else offset
        return cls(
            index=index,  #type: ignore
            targets=targets,
            offset=offset,
            depth_reference=self.depth,
        )
Esempio n. 2
0
    def __init__(self,
            index: Index,
            targets: tp.Optional[ArrayGO] = None, # np.ndarray[IndexLevel]
            offset: int = 0,
            own_index: bool = False
            ):
        '''
        Args:
            index: a 1D Index defining outer-most labels to integers in the `targets` ArrayGO.
            offset: integer offset for this level.
            targets: None, or an ArrayGO of IndexLevel objects
            own_index: Boolean to determine whether the Index can be owned by this IndexLevel; if False, a static index will be reused if appropriate for this IndexLevel class.
        '''
        # if self.STATIC != index.STATIC:
        #     raise ErrorInitIndexLevel('incorrect static state in supplied index')
        if not isinstance(index, Index) or index.depth > 1:
            # all derived Index should be depth == 1
            raise ErrorInitIndexLevel('cannot create an IndexLevel from a higher-dimensional Index.')

        if own_index:
            self.index = index
        else:
            self.index = mutable_immutable_index_filter(self.STATIC, index)

        self.targets = targets
        self.offset = offset
Esempio n. 3
0
    def __init__(self,
            index: Index,
            targets: tp.Optional[ArrayGO] = None,
            offset: int = 0,
            own_index: bool = False
            ):
        '''
        Args:
            index: a 1D Index defining outer-most labels to integers in the `targets` ArrayGO.
            offset: integer offset for this level.
            targets: None, or an ArrayGO of IndexLevel objects
            own_index: Boolean to determine whether the Index can be owned by this IndexLevel; if False, a static index will be reused if appropriate for this IndexLevel class.
        '''
        if not isinstance(index, Index) or index.depth > 1:
            # all derived Index should be depth == 1
            raise ErrorInitIndexLevel('cannot create an IndexLevel from a higher-dimensional Index.')
        # NOTE: indices that conatain tuples will take additional work to support; we are not at this time checking for them, though values_at_depth will fail

        if own_index:
            self.index = index
        else:
            self.index = mutable_immutable_index_filter(self.STATIC, index) #type: ignore

        self.targets = targets
        self.offset = offset
        self._depth = None
        self._length = None
Esempio n. 4
0
    def __init__(
        self,
        index: Index,
        targets: tp.Optional[ArrayGO] = None,
        offset: int = 0,
        own_index: bool = False,
        depth_reference: tp.Optional[int] = None,
    ):
        '''
        Args:
            index: a 1D Index defining outer-most labels to integers in the `targets` ArrayGO.
            offset: integer offset for this level.
            targets: None, or an ArrayGO of IndexLevel objects
            own_index: Boolean to determine whether the Index can be owned by this IndexLevel; if False, a static index will be reused if appropriate for this IndexLevel class.
            depth_reference: for zero length Levels, provide the depth if it is greater than 1.
        '''
        if not isinstance(index, Index) or index.depth > 1:
            raise ErrorInitIndexLevel(
                'cannot create an IndexLevel from a higher-dimensional Index.')

        # NOTE: indices that contain tuples will take additional work to support; we are not at this time checking for them, though values_at_depth will fail

        if own_index:
            self.index = index
        else:
            self.index = mutable_immutable_index_filter(self.STATIC,
                                                        index)  #type: ignore

        self.targets = targets
        self.offset = offset

        # NOTE: once _depth is set, is ever re-evaluated over the life of the instance, even if it is an IndexLevelGO
        if len(index) > 0:
            self._depth = 1 if self.targets is None else None
            self._length = None
        else:
            if depth_reference is None:
                raise ErrorInitIndexLevel(
                    'zero length index requires specification of depth_reference'
                )
            self._depth = depth_reference
            self._length = 0
Esempio n. 5
0
    def from_index_items(
            cls: tp.Type[IH],
            items: tp.Iterable[tp.Tuple[tp.Hashable, Index]],
            *,
            index_constructor: tp.Optional[IndexConstructor] = None) -> IH:
        '''
        Given an iterable of pairs of label, :obj:`Index`, produce an :obj:`IndexHierarchy` where the labels are depth 0, the indices are depth 1.

        Args:
            items: iterable of pairs of label, :obj:`Index`.
            index_constructor: Optionally provide index constructor for outermost index.
        '''
        labels = []
        index_levels = []

        offset = 0
        for label, index in items:
            labels.append(label)

            index = mutable_immutable_index_filter(cls.STATIC, index)
            index_levels.append(
                cls._LEVEL_CONSTRUCTOR(index, offset=offset, own_index=True))
            offset += len(index)

        targets = ArrayGO(np.array(index_levels, dtype=object),
                          own_iterable=True)

        index_outer = index_from_optional_constructor(
            labels,
            default_constructor=cls._INDEX_CONSTRUCTOR,
            explicit_constructor=index_constructor)

        return cls(
            cls._LEVEL_CONSTRUCTOR(index=index_outer,
                                   targets=targets,
                                   own_index=True))