Example #1
0
    def get_value(self, series, key):
        """
        Fast lookup of value from 1-dimensional ndarray. Only use this if you
        know what you're doing
        """
        s = com.values_from_object(series)
        try:
            return com.maybe_box(self,
                                 super(PeriodIndex, self).get_value(s, key),
                                 series, key)
        except (KeyError, IndexError):
            try:
                asdt, parsed, reso = parse_time_string(key, self.freq)
                grp = resolution.Resolution.get_freq_group(reso)
                freqn = resolution.get_freq_group(self.freq)

                vals = self._ndarray_values

                # if our data is higher resolution than requested key, slice
                if grp < freqn:
                    iv = Period(asdt, freq=(grp, 1))
                    ord1 = iv.asfreq(self.freq, how='S').ordinal
                    ord2 = iv.asfreq(self.freq, how='E').ordinal

                    if ord2 < vals[0] or ord1 > vals[-1]:
                        raise KeyError(key)

                    pos = np.searchsorted(self._ndarray_values, [ord1, ord2])
                    key = slice(pos[0], pos[1] + 1)
                    return series[key]
                elif grp == freqn:
                    key = Period(asdt, freq=self.freq).ordinal
                    return com.maybe_box(self, self._engine.get_value(s, key),
                                         series, key)
                else:
                    raise KeyError(key)
            except TypeError:
                pass

            period = Period(key, self.freq)
            key = period.value if isna(period) else period.ordinal
            return com.maybe_box(self, self._engine.get_value(s, key),
                                 series, key)
Example #2
0
    def _parsed_string_to_bounds(self, reso: str, parsed: datetime):
        if reso not in [
                "year", "month", "quarter", "day", "hour", "minute", "second"
        ]:
            raise KeyError(reso)

        grp = resolution.Resolution.get_freq_group(reso)
        iv = Period(parsed, freq=(grp, 1))
        return (iv.asfreq(self.freq,
                          how="start"), iv.asfreq(self.freq, how="end"))
Example #3
0
    def get_loc(self, key, method=None, tolerance=None):
        """
        Get integer location for requested label.

        Parameters
        ----------
        key : Period, NaT, str, or datetime
            String or datetime key must be parseable as Period.

        Returns
        -------
        loc : int or ndarray[int64]

        Raises
        ------
        KeyError
            Key is not present in the index.
        TypeError
            If key is listlike or otherwise not hashable.
        """

        if isinstance(key, str):
            try:
                asdt, reso = parse_time_string(key, self.freq)
                key = asdt
            except DateParseError:
                # A string with invalid format
                raise KeyError(f"Cannot interpret '{key}' as period")

        elif is_integer(key):
            # Period constructor will cast to string, which we dont want
            raise KeyError(key)

        try:
            key = Period(key, freq=self.freq)
        except ValueError:
            # we cannot construct the Period
            # as we have an invalid type
            if is_list_like(key):
                raise TypeError(f"'{key}' is an invalid key")
            raise KeyError(key)

        ordinal = key.ordinal if key is not NaT else key.value
        try:
            return self._engine.get_loc(ordinal)
        except KeyError:

            try:
                if tolerance is not None:
                    tolerance = self._convert_tolerance(
                        tolerance, np.asarray(key))
                return self._int64index.get_loc(ordinal, method, tolerance)

            except KeyError:
                raise KeyError(key)
Example #4
0
def _get_ordinal_range(start, end, periods, freq, mult=1):
    if com.count_not_none(start, end, periods) != 2:
        raise ValueError('Of the three parameters: start, end, and periods, '
                         'exactly two must be specified')

    if freq is not None:
        _, mult = frequencies.get_freq_code(freq)

    if start is not None:
        start = Period(start, freq)
    if end is not None:
        end = Period(end, freq)

    is_start_per = isinstance(start, Period)
    is_end_per = isinstance(end, Period)

    if is_start_per and is_end_per and start.freq != end.freq:
        raise ValueError('start and end must have same freq')
    if (start is NaT or end is NaT):
        raise ValueError('start and end must not be NaT')

    if freq is None:
        if is_start_per:
            freq = start.freq
        elif is_end_per:
            freq = end.freq
        else:  # pragma: no cover
            raise ValueError('Could not infer freq from start/end')

    if periods is not None:
        periods = periods * mult
        if start is None:
            data = np.arange(end.ordinal - periods + mult,
                             end.ordinal + 1, mult,
                             dtype=np.int64)
        else:
            data = np.arange(start.ordinal, start.ordinal + periods, mult,
                             dtype=np.int64)
    else:
        data = np.arange(start.ordinal, end.ordinal + 1, mult, dtype=np.int64)

    return data, freq
Example #5
0
    def get_value(self, series, key):
        """
        Fast lookup of value from 1-dimensional ndarray. Only use this if you
        know what you're doing
        """
        if is_integer(key):
            return series.iat[key]

        if isinstance(key, str):
            asdt, reso = parse_time_string(key, self.freq)
            grp = resolution.Resolution.get_freq_group(reso)
            freqn = resolution.get_freq_group(self.freq)

            vals = self._ndarray_values

            # if our data is higher resolution than requested key, slice
            if grp < freqn:
                iv = Period(asdt, freq=(grp, 1))
                ord1 = iv.asfreq(self.freq, how="S").ordinal
                ord2 = iv.asfreq(self.freq, how="E").ordinal

                if ord2 < vals[0] or ord1 > vals[-1]:
                    raise KeyError(key)

                pos = np.searchsorted(self._ndarray_values, [ord1, ord2])
                key = slice(pos[0], pos[1] + 1)
                return series[key]
            elif grp == freqn:
                key = Period(asdt, freq=self.freq)
                loc = self.get_loc(key)
                return series.iloc[loc]
            else:
                raise KeyError(key)

        elif isinstance(key, Period) or key is NaT:
            ordinal = key.ordinal if key is not NaT else NaT.value
            loc = self._engine.get_loc(ordinal)
            return series[loc]

        # slice, PeriodIndex, np.ndarray, List[Period]
        value = Index.get_value(self, series, key)
        return com.maybe_box(self, value, series, key)
Example #6
0
    def searchsorted(self, value, side='left', sorter=None):
        if isinstance(value, Period):
            if value.freq != self.freq:
                msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, value.freqstr)
                raise IncompatibleFrequency(msg)
            value = value.ordinal
        elif isinstance(value, compat.string_types):
            value = Period(value, freq=self.freq).ordinal

        return self._ndarray_values.searchsorted(value, side=side,
                                                 sorter=sorter)
Example #7
0
    def searchsorted(self, value, side="left", sorter=None):
        if isinstance(value, Period):
            if value.freq != self.freq:
                raise raise_on_incompatible(self, value)
            value = value.ordinal
        elif isinstance(value, str):
            try:
                value = Period(value, freq=self.freq).ordinal
            except DateParseError:
                raise KeyError(f"Cannot interpret '{value}' as period")

        return self._ndarray_values.searchsorted(value, side=side, sorter=sorter)
Example #8
0
    def searchsorted(self, value, side="left", sorter=None):
        if isinstance(value, Period) or value is NaT:
            self._data._check_compatible_with(value)
        elif isinstance(value, str):
            try:
                value = Period(value, freq=self.freq)
            except DateParseError:
                raise KeyError(f"Cannot interpret '{value}' as period")
        elif not isinstance(value, PeriodArray):
            raise TypeError(
                "PeriodIndex.searchsorted requires either a Period or PeriodArray"
            )

        return self._data.searchsorted(value, side=side, sorter=sorter)
Example #9
0
    def searchsorted(self, value, side='left', sorter=None):
        if isinstance(value, Period):
            if value.freq != self.freq:
                msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, value.freqstr)
                raise IncompatibleFrequency(msg)
            value = value.ordinal
        elif isinstance(value, compat.string_types):
            try:
                value = Period(value, freq=self.freq).ordinal
            except DateParseError:
                raise KeyError("Cannot interpret '{}' as period".format(value))

        return self._ndarray_values.searchsorted(value, side=side,
                                                 sorter=sorter)
Example #10
0
    def searchsorted(self, value, side="left", sorter=None):
        if isinstance(value, Period):
            if value.freq != self.freq:
                msg = DIFFERENT_FREQ.format(
                    cls=type(self).__name__,
                    own_freq=self.freqstr,
                    other_freq=value.freqstr,
                )
                raise IncompatibleFrequency(msg)
            value = value.ordinal
        elif isinstance(value, str):
            try:
                value = Period(value, freq=self.freq).ordinal
            except DateParseError:
                raise KeyError("Cannot interpret '{}' as period".format(value))

        return self._ndarray_values.searchsorted(value, side=side, sorter=sorter)
Example #11
0
    def wrapper(self, other):
        ordinal_op = getattr(self.asi8, opname)

        if is_list_like(other) and len(other) != len(self):
            raise ValueError("Lengths must match")

        if isinstance(other, str):
            try:
                other = self._scalar_from_string(other)
            except ValueError:
                # string that can't be parsed as Period
                return invalid_comparison(self, other, op)
        elif isinstance(other, int):
            # TODO: sure we want to allow this?  we dont for DTA/TDA
            #  2 tests rely on this
            other = Period(other, freq=self.freq)
            result = ordinal_op(other.ordinal)

        if isinstance(other, Period):
            self._check_compatible_with(other)

            result = ordinal_op(other.ordinal)
        elif isinstance(other, cls):
            self._check_compatible_with(other)

            result = ordinal_op(other.asi8)

            mask = self._isnan | other._isnan
            if mask.any():
                result[mask] = nat_result

            return result
        elif other is NaT:
            result = np.empty(len(self.asi8), dtype=bool)
            result.fill(nat_result)
        else:
            return invalid_comparison(self, other, op)

        if self._hasnans:
            result[self._isnan] = nat_result

        return result
Example #12
0
 def _parsed_string_to_bounds(self, reso, parsed):
     if reso == "year":
         t1 = Period(year=parsed.year, freq="A")
     elif reso == "month":
         t1 = Period(year=parsed.year, month=parsed.month, freq="M")
     elif reso == "quarter":
         q = (parsed.month - 1) // 3 + 1
         t1 = Period(year=parsed.year, quarter=q, freq="Q-DEC")
     elif reso == "day":
         t1 = Period(year=parsed.year,
                     month=parsed.month,
                     day=parsed.day,
                     freq="D")
     elif reso == "hour":
         t1 = Period(
             year=parsed.year,
             month=parsed.month,
             day=parsed.day,
             hour=parsed.hour,
             freq="H",
         )
     elif reso == "minute":
         t1 = Period(
             year=parsed.year,
             month=parsed.month,
             day=parsed.day,
             hour=parsed.hour,
             minute=parsed.minute,
             freq="T",
         )
     elif reso == "second":
         t1 = Period(
             year=parsed.year,
             month=parsed.month,
             day=parsed.day,
             hour=parsed.hour,
             minute=parsed.minute,
             second=parsed.second,
             freq="S",
         )
     else:
         raise KeyError(reso)
     return (t1.asfreq(self.freq,
                       how="start"), t1.asfreq(self.freq, how="end"))
Example #13
0
    def wrapper(self, other):
        op = getattr(self.asi8, opname)
        # We want to eventually defer to the Series or PeriodIndex (which will
        # return here with an unboxed PeriodArray). But before we do that,
        # we do a bit of validation on type (Period) and freq, so that our
        # error messages are sensible
        not_implemented = isinstance(other, (ABCSeries, ABCIndexClass))
        if not_implemented:
            other = other._values

        if isinstance(other, Period):
            if other.freq != self.freq:
                msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr)
                raise IncompatibleFrequency(msg)

            result = op(other.ordinal)
        elif isinstance(other, cls):
            if other.freq != self.freq:
                msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr)
                raise IncompatibleFrequency(msg)

            if not_implemented:
                return NotImplemented
            result = op(other.asi8)

            mask = self._isnan | other._isnan
            if mask.any():
                result[mask] = nat_result

            return result
        elif other is NaT:
            result = np.empty(len(self.asi8), dtype=bool)
            result.fill(nat_result)
        else:
            other = Period(other, freq=self.freq)
            result = op(other.ordinal)

        if self.hasnans:
            result[self._isnan] = nat_result

        return result
Example #14
0
    def wrapper(self, other):
        op = getattr(self.asi8, opname)
        # We want to eventually defer to the Series or PeriodIndex (which will
        # return here with an unboxed PeriodArray). But before we do that,
        # we do a bit of validation on type (Period) and freq, so that our
        # error messages are sensible
        if is_list_like(other) and len(other) != len(self):
            raise ValueError("Lengths must match")

        not_implemented = isinstance(other, (ABCSeries, ABCIndexClass))
        if not_implemented:
            other = other._values

        if isinstance(other, Period):
            self._check_compatible_with(other)

            result = op(other.ordinal)
        elif isinstance(other, cls):
            self._check_compatible_with(other)

            if not_implemented:
                return NotImplemented
            result = op(other.asi8)

            mask = self._isnan | other._isnan
            if mask.any():
                result[mask] = nat_result

            return result
        elif other is NaT:
            result = np.empty(len(self.asi8), dtype=bool)
            result.fill(nat_result)
        else:
            other = Period(other, freq=self.freq)
            result = op(other.ordinal)

        if self._hasnans:
            result[self._isnan] = nat_result

        return result
Example #15
0
    def get_loc(self, key, method=None, tolerance=None):
        """
        Get integer location for requested label

        Returns
        -------
        loc : int
        """
        try:
            return self._engine.get_loc(key)
        except KeyError:
            if is_integer(key):
                raise

            try:
                asdt, parsed, reso = parse_time_string(key, self.freq)
                key = asdt
            except TypeError:
                pass
            except DateParseError:
                # A string with invalid format
                raise KeyError("Cannot interpret '{}' as period".format(key))

            try:
                key = Period(key, freq=self.freq)
            except ValueError:
                # we cannot construct the Period
                # as we have an invalid type
                raise KeyError(key)

            try:
                ordinal = iNaT if key is NaT else key.ordinal
                if tolerance is not None:
                    tolerance = self._convert_tolerance(tolerance,
                                                        np.asarray(key))
                return self._int64index.get_loc(ordinal, method, tolerance)

            except KeyError:
                raise KeyError(key)
Example #16
0
    def _maybe_cast_slice_bound(self, label, side, kind):
        """
        If label is a string or a datetime, cast it to Period.ordinal according
        to resolution.

        Parameters
        ----------
        label : object
        side : {'left', 'right'}
        kind : {'ix', 'loc', 'getitem'}

        Returns
        -------
        bound : Period or object

        Notes
        -----
        Value of `side` parameter should be validated in caller.

        """
        assert kind in ["ix", "loc", "getitem"]

        if isinstance(label, datetime):
            return Period(label, freq=self.freq)
        elif isinstance(label, str):
            try:
                _, parsed, reso = parse_time_string(label, self.freq)
                bounds = self._parsed_string_to_bounds(reso, parsed)
                return bounds[0 if side == "left" else 1]
            except ValueError:
                # string cannot be parsed as datetime-like
                # TODO: we need tests for this case
                raise KeyError(label)
        elif is_integer(label) or is_float(label):
            self._invalid_indexer("slice", label)

        return label
Example #17
0
    def get_value(self, series, key):
        """
        Fast lookup of value from 1-dimensional ndarray. Only use this if you
        know what you're doing
        """
        if is_integer(key):
            return series.iat[key]

        if isinstance(key, str):
            try:
                loc = self._get_string_slice(key)
                return series[loc]
            except (TypeError, ValueError):
                pass

            asdt, reso = parse_time_string(key, self.freq)
            grp = resolution.Resolution.get_freq_group(reso)
            freqn = resolution.get_freq_group(self.freq)

            # _get_string_slice will handle cases where grp < freqn
            assert grp >= freqn

            if grp == freqn:
                key = Period(asdt, freq=self.freq)
                loc = self.get_loc(key)
                return series.iloc[loc]
            else:
                raise KeyError(key)

        elif isinstance(key, Period) or key is NaT:
            ordinal = key.ordinal if key is not NaT else NaT.value
            loc = self._engine.get_loc(ordinal)
            return series[loc]

        # slice, PeriodIndex, np.ndarray, List[Period]
        value = Index.get_value(self, series, key)
        return com.maybe_box(self, value, series, key)
Example #18
0
 def _parsed_string_to_bounds(self, reso, parsed):
     if reso == 'year':
         t1 = Period(year=parsed.year, freq='A')
     elif reso == 'month':
         t1 = Period(year=parsed.year, month=parsed.month, freq='M')
     elif reso == 'quarter':
         q = (parsed.month - 1) // 3 + 1
         t1 = Period(year=parsed.year, quarter=q, freq='Q-DEC')
     elif reso == 'day':
         t1 = Period(year=parsed.year,
                     month=parsed.month,
                     day=parsed.day,
                     freq='D')
     elif reso == 'hour':
         t1 = Period(year=parsed.year,
                     month=parsed.month,
                     day=parsed.day,
                     hour=parsed.hour,
                     freq='H')
     elif reso == 'minute':
         t1 = Period(year=parsed.year,
                     month=parsed.month,
                     day=parsed.day,
                     hour=parsed.hour,
                     minute=parsed.minute,
                     freq='T')
     elif reso == 'second':
         t1 = Period(year=parsed.year,
                     month=parsed.month,
                     day=parsed.day,
                     hour=parsed.hour,
                     minute=parsed.minute,
                     second=parsed.second,
                     freq='S')
     else:
         raise KeyError(reso)
     return (t1.asfreq(self.freq,
                       how='start'), t1.asfreq(self.freq, how='end'))
Example #19
0
def _format_coord(freq, t, y):
    return "t = {0}  y = {1:8f}".format(Period(ordinal=int(t), freq=freq), y)
Example #20
0
def _format_coord(freq, t, y):
    time_period = Period(ordinal=int(t), freq=freq)
    return f"t = {time_period}  y = {y:8f}"
Example #21
0
    def wrapper(self, other):
        ordinal_op = getattr(self.asi8, opname)

        if is_list_like(other) and len(other) != len(self):
            raise ValueError("Lengths must match")

        if isinstance(other, str):
            try:
                other = self._scalar_from_string(other)
            except ValueError:
                # string that can't be parsed as Period
                return invalid_comparison(self, other, op)
        elif isinstance(other, int):
            # TODO: sure we want to allow this?  we dont for DTA/TDA
            #  2 tests rely on this
            other = Period(other, freq=self.freq)
            result = ordinal_op(other.ordinal)

        if isinstance(other, Period):
            self._check_compatible_with(other)

            result = ordinal_op(other.ordinal)

        elif other is NaT:
            result = np.empty(len(self.asi8), dtype=bool)
            result.fill(nat_result)

        elif not is_list_like(other):
            return invalid_comparison(self, other, op)

        else:
            if isinstance(other, list):
                # TODO: could use pd.Index to do inference?
                other = np.array(other)

            if not isinstance(other, (np.ndarray, cls)):
                return invalid_comparison(self, other, op)

            if is_object_dtype(other):
                with np.errstate(all="ignore"):
                    result = ops.comp_method_OBJECT_ARRAY(
                        op, self.astype(object), other
                    )
                o_mask = isna(other)

            elif not is_period_dtype(other):
                # e.g. is_timedelta64_dtype(other)
                return invalid_comparison(self, other, op)

            else:
                assert isinstance(other, cls), type(other)

                self._check_compatible_with(other)

                result = ordinal_op(other.asi8)
                o_mask = other._isnan

            if o_mask.any():
                result[o_mask] = nat_result

        if self._hasnans:
            result[self._isnan] = nat_result

        return result
Example #22
0
 def _scalar_from_string(self, value: str) -> Period:
     return Period(value, freq=self.freq)
Example #23
0
 def setup(self, freq):
     self.per = Period("2012-06-01", freq=freq)
Example #24
0
 def time_period_constructor(self, freq, is_offset):
     Period("2012-06-01", freq=freq)
Example #25
0
    def get_loc(self, key, method=None, tolerance=None):
        """
        Get integer location for requested label.

        Parameters
        ----------
        key : Period, NaT, str, or datetime
            String or datetime key must be parseable as Period.

        Returns
        -------
        loc : int or ndarray[int64]

        Raises
        ------
        KeyError
            Key is not present in the index.
        TypeError
            If key is listlike or otherwise not hashable.
        """
        orig_key = key

        if not is_scalar(key):
            raise InvalidIndexError(key)

        if isinstance(key, str):

            try:
                loc = self._get_string_slice(key)
                return loc
            except (TypeError, ValueError):
                pass

            try:
                asdt, reso = parse_time_string(key, self.freq)
            except DateParseError as err:
                # A string with invalid format
                raise KeyError(f"Cannot interpret '{key}' as period") from err

            grp = resolution.Resolution.get_freq_group(reso)
            freqn = resolution.get_freq_group(self.freq)

            # _get_string_slice will handle cases where grp < freqn
            assert grp >= freqn

            if grp == freqn:
                key = Period(asdt, freq=self.freq)
                loc = self.get_loc(key, method=method, tolerance=tolerance)
                return loc
            elif method is None:
                raise KeyError(key)
            else:
                key = asdt

        elif is_integer(key):
            # Period constructor will cast to string, which we dont want
            raise KeyError(key)

        try:
            key = Period(key, freq=self.freq)
        except ValueError as err:
            # we cannot construct the Period
            raise KeyError(orig_key) from err

        try:
            return Index.get_loc(self, key, method, tolerance)
        except KeyError as err:
            raise KeyError(orig_key) from err
Example #26
0
 def _scalar_from_string(self, value):
     # type: (str) -> Period
     return Period(value, freq=self.freq)