def test_index_datetime_nanosecond_a(self) -> None: index1 = IndexNanosecond(('2020-01-01', '2020-02-01')) index2 = IndexYearMonth(index1) self.assertEqual( index2.values.tolist(), [datetime.date(2020, 1, 1), datetime.date(2020, 2, 1)] )
def from_pandas( cls, value: 'pandas.DataFrame', ) -> 'IndexBase': ''' Given a Pandas index, return the appropriate IndexBase derived class. ''' import pandas from static_frame import Index from static_frame import IndexGO from static_frame import IndexHierarchy from static_frame import IndexHierarchyGO from static_frame import IndexNanosecond from static_frame import IndexNanosecondGO from static_frame.core.index_datetime import IndexDatetime if isinstance(value, pandas.MultiIndex): # iterating over a hierarchucal index will iterate over labels name = tuple(value.names) if not cls.STATIC: return IndexHierarchyGO.from_labels(value, name=name) return IndexHierarchy.from_labels(value, name=name) elif isinstance(value, pandas.DatetimeIndex): # if IndexDatetime, use cls, else use IndexNanosecond if issubclass(cls, IndexDatetime): return cls(value, name=value.name) else: if not cls.STATIC: return IndexNanosecondGO(value, name=value.name) return IndexNanosecond(value, name=value.name) if not cls.STATIC: return IndexGO(value, name=value.name) return Index(value, name=value.name)
def test_index_nanosecond_a(self) -> None: idx1 = IndexNanosecond(('2018-01-01T03:30', '2018-01-01T03:45', '2019-01-02T03:45')) self.assertTrue(len(idx1.loc['2019']), 1) #type: ignore self.assertTrue(len(idx1.loc['2018']), 2) #type: ignore # NP reduces nanoseconds to integers self.assertEqual(idx1.values.tolist(), [1514777400000000000, 1514778300000000000, 1546400700000000000])
def from_pandas( cls, value: 'pandas.Index', ) -> 'IndexBase': ''' Given a Pandas index, return the appropriate IndexBase derived class. ''' import pandas if not isinstance(value, pandas.Index): raise ErrorInitIndex( f'from_pandas must be called with a Pandas Index object, not: {type(value)}' ) from static_frame import Index from static_frame import IndexGO from static_frame import IndexHierarchy from static_frame import IndexHierarchyGO from static_frame import IndexNanosecond from static_frame import IndexNanosecondGO from static_frame.core.index_datetime import IndexDatetime if isinstance(value, pandas.MultiIndex): # iterating over a hierarchical index will iterate over labels name: tp.Optional[tp.Tuple[tp.Hashable, ...]] = tuple(value.names) # if not assigned Pandas returns None for all components, which will raise issue if trying to unset this index. if all(n is None for n in name): #type: ignore name = None depth = value.nlevels if not cls.STATIC: return IndexHierarchyGO.from_labels(value, name=name, depth_reference=depth) return IndexHierarchy.from_labels(value, name=name, depth_reference=depth) elif isinstance(value, pandas.DatetimeIndex): # if IndexDatetime, use cls, else use IndexNanosecond if issubclass(cls, IndexDatetime): return cls(value, name=value.name) else: if not cls.STATIC: return IndexNanosecondGO(value, name=value.name) return IndexNanosecond(value, name=value.name) if not cls.STATIC: return IndexGO(value, name=value.name) return Index(value, name=value.name)
def from_pandas(cls, value: 'pandas.Index', ) -> 'IndexBase': ''' Given a Pandas index, return the appropriate IndexBase derived class. ''' import pandas if not isinstance(value, pandas.Index): raise ErrorInitIndex(f'from_pandas must be called with a Pandas Index object, not: {type(value)}') from static_frame import Index from static_frame import IndexGO from static_frame import IndexHierarchy from static_frame import IndexHierarchyGO from static_frame import IndexNanosecond from static_frame import IndexNanosecondGO from static_frame.core.index_datetime import IndexDatetime if isinstance(value, pandas.MultiIndex): if value.has_duplicates: raise ErrorInitIndex(f'cannot create IndexHierarchy from a MultiIndex with duplicates: {value}') # iterating over a hierarchical index will iterate over labels name: tp.Optional[tp.Tuple[tp.Hashable, ...]] = tuple(value.names) # if not assigned Pandas returns None for all components, which will raise issue if trying to unset this index. if all(n is None for n in name): #type: ignore name = None hierarchy_constructor = IndexHierarchy if cls.STATIC else IndexHierarchyGO def build_index(pd_idx: pandas.Index) -> Index: # NOTE: Newer versions of pandas will not require Python date objects to live inside # a DatetimeIndex. Instead, it will be a regular Index with dtype=object. # Only numpy datetime objects are put into a DatetimeIndex. if isinstance(pd_idx, pandas.DatetimeIndex): constructor: tp.Type[Index] = IndexNanosecond else: constructor = Index if cls.STATIC: return constructor(pd_idx, name=pd_idx.name) return tp.cast(Index, constructor._MUTABLE_CONSTRUCTOR(pd_idx)) indices: tp.List[Index] = [] indexers: np.ndarray = np.empty((value.nlevels, len(value)), dtype=DTYPE_INT_DEFAULT) for i, (levels, codes) in enumerate(zip(value.levels, value.codes)): indexers[i] = codes indices.append(build_index(levels)) indexers.flags.writeable = False return hierarchy_constructor( indices=indices, indexers=indexers, name=name, ) elif isinstance(value, pandas.DatetimeIndex): # if IndexDatetime, use cls, else use IndexNanosecond if issubclass(cls, IndexDatetime): return cls(value, name=value.name) else: if not cls.STATIC: return IndexNanosecondGO(value, name=value.name) return IndexNanosecond(value, name=value.name) if not cls.STATIC: return IndexGO(value, name=value.name) return Index(value, name=value.name)