示例#1
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)
示例#2
0
文件: period.py 项目: ywpark1/pandas
    def _sub_period(self, other):
        # If the operation is well-defined, we return an object-Index
        # of DateOffsets.  Null entries are filled with pd.NaT
        if self.freq != other.freq:
            msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr)
            raise IncompatibleFrequency(msg)

        asi8 = self.asi8
        new_data = asi8 - other.ordinal
        new_data = np.array([self.freq * x for x in new_data])

        if self.hasnans:
            new_data[self._isnan] = NaT

        return new_data
示例#3
0
文件: period.py 项目: wleepang/pandas
    def _add_delta_td(self, other):
        assert isinstance(other, (timedelta, np.timedelta64, Tick))
        nanos = delta_to_nanoseconds(other)
        own_offset = frequencies.to_offset(self.freq.rule_code)

        if isinstance(own_offset, Tick):
            offset_nanos = delta_to_nanoseconds(own_offset)
            if np.all(nanos % offset_nanos == 0):
                return self.shift(nanos // offset_nanos)

        # raise when input doesn't have freq
        raise IncompatibleFrequency("Input has different freq from "
                                    "{cls}(freq={freqstr})"
                                    .format(cls=type(self).__name__,
                                            freqstr=self.freqstr))
示例#4
0
    def get_indexer_non_unique(self, target):
        target = ensure_index(target)

        if isinstance(target, PeriodIndex):
            target = target.asi8
            if hasattr(target, "freq") and target.freq != self.freq:
                msg = DIFFERENT_FREQ.format(
                    cls=type(self).__name__,
                    own_freq=self.freqstr,
                    other_freq=target.freqstr,
                )
                raise IncompatibleFrequency(msg)

        indexer, missing = self._int64index.get_indexer_non_unique(target)
        return ensure_platform_int(indexer), missing
示例#5
0
    def get_indexer(self, target, method=None, limit=None, tolerance=None):
        target = ensure_index(target)

        if hasattr(target, 'freq') and target.freq != self.freq:
            msg = DIFFERENT_FREQ.format(cls=type(self).__name__,
                                        own_freq=self.freqstr,
                                        other_freq=target.freqstr)
            raise IncompatibleFrequency(msg)

        if isinstance(target, PeriodIndex):
            target = target.asi8

        if tolerance is not None:
            tolerance = self._convert_tolerance(tolerance, target)
        return Index.get_indexer(self._int64index, target, method, limit,
                                 tolerance)
示例#6
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)
示例#7
0
文件: period.py 项目: Aathi410/Pro123
    def _require_matching_freq(self, other, base: bool = False) -> None:
        # See also arrays.period.raise_on_incompatible
        if isinstance(other, BaseOffset):
            other_freq = other
        else:
            other_freq = other.freq

        if base:
            condition = self.freq.base != other_freq.base
        else:
            condition = self.freq != other_freq

        if condition:
            msg = DIFFERENT_FREQ.format(
                cls=type(self).__name__,
                own_freq=self.freqstr,
                other_freq=other_freq.freqstr,
            )
            raise IncompatibleFrequency(msg)
示例#8
0
文件: period.py 项目: tnir/pandas
    def _add_timedelta_arraylike(
            self, other: TimedeltaArray | npt.NDArray[np.timedelta64]
    ) -> PeriodArray:
        """
        Parameters
        ----------
        other : TimedeltaArray or ndarray[timedelta64]

        Returns
        -------
        PeriodArray
        """
        freq = self.freq
        if not isinstance(freq, Tick):
            # We cannot add timedelta-like to non-tick PeriodArray
            raise TypeError(
                f"Cannot add or subtract timedelta64[ns] dtype from {self.dtype}"
            )

        dtype = np.dtype(f"m8[{freq._td64_unit}]")

        try:
            delta = astype_overflowsafe(np.asarray(other),
                                        dtype=dtype,
                                        copy=False,
                                        round_ok=False)
        except ValueError as err:
            # e.g. if we have minutes freq and try to add 30s
            # "Cannot losslessly convert units"
            raise IncompatibleFrequency(
                "Cannot add/subtract timedelta-like from PeriodArray that is "
                "not an integer multiple of the PeriodArray's freq.") from err

        b_mask = np.isnat(delta)

        res_values = algos.checked_add_with_arr(self.asi8,
                                                delta.view("i8"),
                                                arr_mask=self._isnan,
                                                b_mask=b_mask)
        np.putmask(res_values, self._isnan | b_mask, iNaT)
        return type(self)(res_values, freq=self.freq)
示例#9
0
    def take(self, indices, allow_fill=False, fill_value=None):
        if allow_fill:
            if isna(fill_value):
                fill_value = iNaT
            elif isinstance(fill_value, Period):
                if self.freq != fill_value.freq:
                    msg = DIFFERENT_FREQ_INDEX.format(self.freq.freqstr,
                                                      fill_value.freqstr)
                    raise IncompatibleFrequency(msg)

                fill_value = fill_value.ordinal
            else:
                msg = "'fill_value' should be a Period. Got '{}'."
                raise ValueError(msg.format(fill_value))

        new_values = algos.take(self._data,
                                indices,
                                allow_fill=allow_fill,
                                fill_value=fill_value)

        return type(self)(new_values, self.freq)
示例#10
0
    def _sub_period_array(self, other):
        """
        Subtract a Period Array/Index from self.  This is only valid if self
        is itself a Period Array/Index, raises otherwise.  Both objects must
        have the same frequency.

        Parameters
        ----------
        other : PeriodIndex or PeriodArray

        Returns
        -------
        result : np.ndarray[object]
            Array of DateOffset objects; nulls represented by NaT
        """
        if not is_period_dtype(self):
            raise TypeError("cannot subtract {dtype}-dtype from {cls}".format(
                dtype=other.dtype, cls=type(self).__name__))

        if len(self) != len(other):
            raise ValueError("cannot subtract arrays/indices of "
                             "unequal length")
        if self.freq != other.freq:
            msg = DIFFERENT_FREQ.format(cls=type(self).__name__,
                                        own_freq=self.freqstr,
                                        other_freq=other.freqstr)
            raise IncompatibleFrequency(msg)

        new_values = checked_add_with_arr(self.asi8,
                                          -other.asi8,
                                          arr_mask=self._isnan,
                                          b_mask=other._isnan)

        new_values = np.array([self.freq.base * x for x in new_values])
        if self._hasnans or other._hasnans:
            mask = (self._isnan) | (other._isnan)
            new_values[mask] = NaT
        return new_values
示例#11
0
文件: period.py 项目: tnir/pandas
def validate_dtype_freq(
        dtype, freq: BaseOffsetT | timedelta | str | None) -> BaseOffsetT:
    """
    If both a dtype and a freq are available, ensure they match.  If only
    dtype is available, extract the implied freq.

    Parameters
    ----------
    dtype : dtype
    freq : DateOffset or None

    Returns
    -------
    freq : DateOffset

    Raises
    ------
    ValueError : non-period dtype
    IncompatibleFrequency : mismatch between dtype and freq
    """
    if freq is not None:
        # error: Incompatible types in assignment (expression has type
        # "BaseOffset", variable has type "Union[BaseOffsetT, timedelta,
        # str, None]")
        freq = to_offset(freq)  # type: ignore[assignment]

    if dtype is not None:
        dtype = pandas_dtype(dtype)
        if not is_period_dtype(dtype):
            raise ValueError("dtype must be PeriodDtype")
        if freq is None:
            freq = dtype.freq
        elif freq != dtype.freq:
            raise IncompatibleFrequency(
                "specified freq and dtype are different")
    # error: Incompatible return value type (got "Union[BaseOffset, Any, None]",
    # expected "BaseOffset")
    return freq  # type: ignore[return-value]
示例#12
0
    def _add_delta(self, other):
        """
        Add a timedelta-like, Tick, or TimedeltaIndex-like object
        to self, yielding a new PeriodArray

        Parameters
        ----------
        other : {timedelta, np.timedelta64, Tick,
                 TimedeltaIndex, ndarray[timedelta64]}

        Returns
        -------
        result : PeriodArray
        """
        if not isinstance(self.freq, Tick):
            # We cannot add timedelta-like to non-tick PeriodArray
            raise IncompatibleFrequency("Input has different freq from "
                                        "{cls}(freq={freqstr})"
                                        .format(cls=type(self).__name__,
                                                freqstr=self.freqstr))

        new_ordinals = super(PeriodArray, self)._add_delta(other)
        return type(self)(new_ordinals, freq=self.freq)
示例#13
0
    def __init__(self, values, freq=None, copy=False):
        if freq is not None:
            freq = Period._maybe_convert_freq(freq)

        if isinstance(values, ABCSeries):
            values = values._values
            if not isinstance(values, type(self)):
                raise TypeError("Incorrect dtype")

        elif isinstance(values, ABCPeriodIndex):
            values = values._values

        if isinstance(values, type(self)):
            if freq is not None and freq != values.freq:
                msg = DIFFERENT_FREQ_INDEX.format(values.freq.freqstr,
                                                  freq.freqstr)
                raise IncompatibleFrequency(msg)
            values, freq = values._data, values.freq

        values = np.array(values, dtype='int64', copy=copy)
        self._data = values
        if freq is None:
            raise ValueError('freq is not specified and cannot be inferred')
        self._dtype = PeriodDtype(freq)
示例#14
0
    def __new__(cls,
                data=None,
                ordinal=None,
                freq=None,
                start=None,
                end=None,
                periods=None,
                copy=False,
                name=None,
                tz=None,
                dtype=None,
                **kwargs):

        if periods is not None:
            if is_float(periods):
                periods = int(periods)
            elif not is_integer(periods):
                msg = 'periods must be a number, got {periods}'
                raise TypeError(msg.format(periods=periods))

        if name is None and hasattr(data, 'name'):
            name = data.name

        if dtype is not None:
            dtype = pandas_dtype(dtype)
            if not is_period_dtype(dtype):
                raise ValueError('dtype must be PeriodDtype')
            if freq is None:
                freq = dtype.freq
            elif freq != dtype.freq:
                msg = 'specified freq and dtype are different'
                raise IncompatibleFrequency(msg)

        # coerce freq to freq object, otherwise it can be coerced elementwise
        # which is slow
        if freq:
            freq = Period._maybe_convert_freq(freq)

        if data is None:
            if ordinal is not None:
                data = np.asarray(ordinal, dtype=np.int64)
            else:
                data, freq = cls._generate_range(start, end, periods, freq,
                                                 kwargs)
            return cls._from_ordinals(data, name=name, freq=freq)

        if isinstance(data, PeriodIndex):
            if freq is None or freq == data.freq:  # no freq change
                freq = data.freq
                data = data._values
            else:
                base1, _ = _gfc(data.freq)
                base2, _ = _gfc(freq)
                data = period.period_asfreq_arr(data._values, base1, base2, 1)
            return cls._simple_new(data, name=name, freq=freq)

        # not array / index
        if not isinstance(
                data, (np.ndarray, PeriodIndex, DatetimeIndex, Int64Index)):
            if is_scalar(data) or isinstance(data, Period):
                cls._scalar_data_error(data)

            # other iterable of some kind
            if not isinstance(data, (list, tuple)):
                data = list(data)

            data = np.asarray(data)

        # datetime other than period
        if is_datetime64_dtype(data.dtype):
            data = dt64arr_to_periodarr(data, freq, tz)
            return cls._from_ordinals(data, name=name, freq=freq)

        # check not floats
        if infer_dtype(data) == 'floating' and len(data) > 0:
            raise TypeError("PeriodIndex does not allow "
                            "floating point in construction")

        # anything else, likely an array of strings or periods
        data = _ensure_object(data)
        freq = freq or period.extract_freq(data)
        data = period.extract_ordinals(data, freq)
        return cls._from_ordinals(data, name=name, freq=freq)
示例#15
0
 def _check_compatible_with(self, other):
     if self.freqstr != other.freqstr:
         msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr)
         raise IncompatibleFrequency(msg)
示例#16
0
    def __new__(cls,
                data=None,
                ordinal=None,
                freq=None,
                start=None,
                end=None,
                periods=None,
                tz=None,
                dtype=None,
                copy=False,
                name=None,
                **fields):

        valid_field_set = {
            'year', 'month', 'day', 'quarter', 'hour', 'minute', 'second'
        }

        if not set(fields).issubset(valid_field_set):
            raise TypeError(
                '__new__() got an unexpected keyword argument {}'.format(
                    list(set(fields) - valid_field_set)[0]))

        if name is None and hasattr(data, 'name'):
            name = data.name

        if data is None and ordinal is None:
            # range-based.
            if periods is not None:
                if is_float(periods):
                    periods = int(periods)

                elif not is_integer(periods):
                    msg = 'periods must be a number, got {periods}'
                    raise TypeError(msg.format(periods=periods))

            data, freq = PeriodArray._generate_range(start, end, periods, freq,
                                                     fields)
            data = PeriodArray(data, freq=freq)
        else:
            if freq is None and dtype is not None:
                freq = PeriodDtype(dtype).freq
            elif freq and dtype:
                freq = PeriodDtype(freq).freq
                dtype = PeriodDtype(dtype).freq

                if freq != dtype:
                    msg = "specified freq and dtype are different"
                    raise IncompatibleFrequency(msg)

            # PeriodIndex allow PeriodIndex(period_index, freq=different)
            # Let's not encourage that kind of behavior in PeriodArray.

            if freq and isinstance(data, cls) and data.freq != freq:
                # TODO: We can do some of these with no-copy / coercion?
                # e.g. D -> 2D seems to be OK
                data = data.asfreq(freq)

            if data is None and ordinal is not None:
                # we strangely ignore `ordinal` if data is passed.
                ordinal = np.asarray(ordinal, dtype=np.int64)
                data = PeriodArray(ordinal, freq)
            else:
                # don't pass copy here, since we copy later.
                data = period_array(data=data, freq=freq)

        if copy:
            data = data.copy()

        return cls._simple_new(data, name=name)