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)
Beispiel #5
0
    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)