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, )
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
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
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
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))