def __init__(self, labels: IndexInitializer, *, loc_is_iloc: bool = False, name: tp.Hashable = None, dtype: DtypeSpecifier = None) -> None: self._recache = False self._map = None positions = None # NOTE: this will not, and shold not, catch IndexHierarchy if issubclass(labels.__class__, Index): # get a reference to the immutable arrays # even if this is an IndexGO index, we can take the cached arrays, assuming they are up to date if labels.STATIC: # can take the map self._map = labels._map if labels._recache: labels._update_array_cache() positions = labels._positions loc_is_iloc = labels._loc_is_iloc if name is None and labels.name is not None: name = labels.name # immutable, so no copy necessary labels = labels._labels self._name = name if name is None else name_filter(name) if self._map is None: self._map = self._get_map(labels, positions) if dtype is None: dtype_extract = self._DTYPE # set in specialized Index classes else: # dtype is not None if self._DTYPE is not None and dtype != self._DTYPE: raise RuntimeError('invalid dtype argument for this Index', dtype, self._DTYPE) # self._DTYPE is None, dtype is not None, use dtype dtype_extract = dtype # this might be NP array, or a list, depending on if static or grow only self._labels = self._extract_labels(self._map, labels, dtype_extract) self._positions = self._extract_positions(self._map, positions) if self._DTYPE and self._labels.dtype != self._DTYPE: raise RuntimeError('invalid label dtype for this Index', self._labels.dtype, self._DTYPE) if len(self._map) != len(self._labels): raise KeyError('labels have non-unique values') # NOTE: automatic discovery is possible, but not yet implemented self._loc_is_iloc = loc_is_iloc
def __init__(self, labels: IndexInitializer, loc_is_iloc: bool=False, dtype: DtypeSpecifier=None ) -> None: ''' Args: labels: Initializer of the Index. If an Index or IndexGO object is provided, appropriate usage of those objects is implemented. An Index cannot be initialized from an IndexHierarhy directly (instead, pass the indices lables via .values). ''' self._recache = False self._map = None positions = None # NOTE: this will not, and shold not, catch IndexHierarchy if issubclass(labels.__class__, Index): # get a reference to the immutable arrays # even if this is an IndexGO index, we can take the cached arrays, assuming they are up to date if labels.STATIC: # can take the map self._map = labels._map if labels._recache: labels._update_array_cache() positions = labels._positions loc_is_iloc = labels._loc_is_iloc labels = labels._labels if self._map is None: self._map = self._get_map(labels, positions) # this might be NP array, or a list, depending on if static or grow only self._labels = self._extract_labels(self._map, labels, dtype) self._positions = self._extract_positions(self._map, positions) if self._DTYPE and self._labels.dtype != self._DTYPE: raise Exception('invalide label dtype for this index', self._labels.dtype, self._DTYPE) if len(self._map) != len(self._labels): raise KeyError('labels have non-unique values') # NOTE: automatic discovery is possible, but not yet implemented self._loc_is_iloc = loc_is_iloc
def __init__(self, labels: IndexInitializer, *, loc_is_iloc: bool = False, name: tp.Hashable = None, dtype: DtypeSpecifier = None ) -> None: self._recache = False self._map = None positions = None # resolve the targetted labels dtype, by lookin at the class attr _DTYPE and/or the passed dtype argument if dtype is None: dtype_extract = self._DTYPE # set in some specialized Index classes else: # passed dtype is not None if self._DTYPE is not None and dtype != self._DTYPE: raise RuntimeError('invalid dtype argument for this Index', dtype, self._DTYPE) # self._DTYPE is None, passed dtype is not None, use dtype dtype_extract = dtype # handle all Index subclasses # check isinstance(labels, IndexBase) if issubclass(labels.__class__, IndexBase): if labels._recache: labels._update_array_cache() if name is None and labels.name is not None: name = labels.name # immutable, so no copy necessary if labels.depth == 1: # not an IndexHierarchy if labels.STATIC: # can take the map self._map = labels._map # get a reference to the immutable arrays, even if this is an IndexGO index, we can take the cached arrays, assuming they are up to date positions = labels._positions loc_is_iloc = labels._loc_is_iloc labels = labels._labels else: # IndexHierarchy # will be a generator of tuples; already updated caches labels = array2d_to_tuples(labels._labels) elif hasattr(labels, 'values'): # it is a Series or similar array = labels.values if array.ndim == 1: labels = array else: labels = array2d_to_tuples(array) if self._DTYPE is not None: # do not need to check arrays, as will and checked to match dtype_extract in _extract_labels if not isinstance(labels, np.ndarray): # for now, assume that if _DTYPE is defined, we have a date labels = (to_datetime64(v, dtype_extract) for v in labels) else: # coerce to target type labels = labels.astype(dtype_extract) self._name = name if name is None else name_filter(name) if self._map is None: self._map = self._get_map(labels, positions) # this might be NP array, or a list, depending on if static or grow only; if an array, dtype will be compared with passed dtype_extract self._labels = self._extract_labels(self._map, labels, dtype_extract) self._positions = self._extract_positions(self._map, positions) if self._DTYPE and self._labels.dtype != self._DTYPE: raise RuntimeError('invalid label dtype for this Index', self._labels.dtype, self._DTYPE) if len(self._map) != len(self._labels): raise KeyError(f'labels ({len(self._labels)}) have non-unique values ({len(self._map)})') # NOTE: automatic discovery is possible, but not yet implemented self._loc_is_iloc = loc_is_iloc
def __init__(self, labels: IndexInitializer, *, loc_is_iloc: bool = False, name: NameType = NAME_DEFAULT, dtype: DtypeSpecifier = None) -> None: self._recache: bool = False self._map: tp.Optional[FrozenAutoMap] = None positions = None is_typed = self._DTYPE is not None # resolve the targetted labels dtype, by lookin at the class attr _DTYPE and/or the passed dtype argument if dtype is None: dtype_extract = self._DTYPE # set in some specialized Index classes else: # passed dtype is not None if is_typed and dtype != self._DTYPE: # NOTE: should never get to this branch, as derived Index classes that set _DTYPE remove dtype from __init__ raise ErrorInitIndex('invalid dtype argument for this Index', dtype, self._DTYPE) #pragma: no cover # self._DTYPE is None, passed dtype is not None, use dtype dtype_extract = dtype #----------------------------------------------------------------------- # handle all Index subclasses if isinstance(labels, IndexBase): if labels._recache: labels._update_array_cache() if name is NAME_DEFAULT: name = labels.name # immutable, so no copy necessary if isinstance(labels, Index): # not an IndexHierarchy if (labels.STATIC and self.STATIC and dtype is None): if not is_typed or (is_typed and self._DTYPE == labels.dtype): # can take the map if static and if types in the dict are the same as those in the labels (or to become the labels after conversion) self._map = labels._map # get a reference to the immutable arrays, even if this is an IndexGO index, we can take the cached arrays, assuming they are up to date; for datetime64 indices, we might need to translate to a different type positions = labels._positions loc_is_iloc = labels._map is None labels = labels._labels else: # IndexHierarchy # will be a generator of tuples; already updated caches labels = array2d_to_tuples(labels.__iter__()) elif isinstance(labels, ContainerOperand): # it is a Series or similar array = labels.values if array.ndim == 1: labels = array else: labels = array2d_to_tuples(array) # else: assume an iterable suitable for labels usage #----------------------------------------------------------------------- if is_typed: # do not need to check arrays, as will and checked to match dtype_extract in _extract_labels if not isinstance(labels, np.ndarray): # for now, assume that if _DTYPE is defined, we have a date labels = (to_datetime64(v, dtype_extract) for v in labels) # coerce to target type elif labels.dtype != dtype_extract: labels = labels.astype(dtype_extract) labels.flags.writeable = False #type: ignore self._name = None if name is NAME_DEFAULT else name_filter(name) if self._map is None: # if _map not shared from another Index if not loc_is_iloc: try: self._map = FrozenAutoMap( labels) if self.STATIC else AutoMap(labels) except ValueError: # Automap will raise ValueError of non-unique values are encountered pass if self._map is None: raise ErrorInitIndex( f'labels ({len(tuple(labels))}) have non-unique values ({len(set(labels))})' ) size = len(self._map) else: # must assume labels are unique # labels must not be a generator, but we assume that internal clients that provided loc_is_iloc will not give a generator size = len(labels) #type: ignore if positions is None: positions = PositionsAllocator.get(size) else: # map shared from another Index size = len(self._map) # this might be NP array, or a list, depending on if static or grow only; if an array, dtype will be compared with passed dtype_extract self._labels = self._extract_labels(self._map, labels, dtype_extract) self._positions = self._extract_positions(size, positions) if self._DTYPE and self._labels.dtype != self._DTYPE: raise ErrorInitIndex( 'invalid label dtype for this Index', #pragma: no cover self._labels.dtype, self._DTYPE)