def test_tick_division(cls): off = cls(10) assert off / cls(5) == 2 assert off / 2 == cls(5) assert off / 2.0 == cls(5) assert off / off.delta == 1 assert off / off.delta.to_timedelta64() == 1 assert off / Nano(1) == off.delta / Nano(1).delta if cls is not Nano: # A case where we end up with a smaller class result = off / 1000 assert isinstance(result, offsets.Tick) assert not isinstance(result, cls) assert result.delta == off.delta / 1000 if cls._nanos_inc < Timedelta(seconds=1).value: # Case where we end up with a bigger class result = off / 0.001 assert isinstance(result, offsets.Tick) assert not isinstance(result, cls) assert result.delta == off.delta / 0.001
def test_NanosecondGeneric(): timestamp = Timestamp(datetime(2010, 1, 1)) assert timestamp.nanosecond == 0 result = timestamp + Nano(10) assert result.nanosecond == 10 reverse_result = Nano(10) + timestamp assert reverse_result.nanosecond == 10
def test_qcut_nat(self, s): # GH 19768 intervals = IntervalIndex.from_tuples( [(s[0] - Nano(), s[2] - Day()), np.nan, (s[2] - Day(), s[2])]) expected = Series(Categorical(intervals, ordered=True)) result = qcut(s, 2) tm.assert_series_equal(result, expected)
def test_delta_to_tick(): delta = timedelta(3) tick = delta_to_tick(delta) assert tick == offsets.Day(3) td = Timedelta(nanoseconds=5) tick = delta_to_tick(td) assert tick == Nano(5)
def test_qcut_nat(ser): # see gh-19768 intervals = IntervalIndex.from_tuples( [(ser[0] - Nano(), ser[2] - Day()), np.nan, (ser[2] - Day(), ser[2])], "right") expected = Series(Categorical(intervals, ordered=True)) result = qcut(ser, 2) tm.assert_series_equal(result, expected)
def test_tick_zero(cls1, cls2): assert cls1(0) == cls2(0) assert cls1(0) + cls2(0) == cls1(0) if cls1 is not Nano: assert cls1(2) + cls2(0) == cls1(2) if cls1 is Nano: assert cls1(2) + Nano(0) == cls1(2)
class FromDictwithTimestamp: params = [Nano(1), Hour(1)] param_names = ["offset"] def setup(self, offset): N = 10**3 idx = date_range(Timestamp("1/1/1900"), freq=offset, periods=N) df = DataFrame(np.random.randn(N, 10), index=idx) self.d = df.to_dict() def time_dict_with_timestamp_offsets(self, offset): DataFrame(self.d)
def test_tick_mul_float(): off = Micro(2) # Case where we retain type result = off * 1.5 expected = Micro(3) assert result == expected assert isinstance(result, Micro) # Case where we bump up to the next type result = off * 1.25 expected = Nano(2500) assert result == expected assert isinstance(result, Nano)
class FromDictwithTimestamp(object): params = [Nano(1), Hour(1)] param_names = ['offset'] def setup(self, offset): N = 10**3 np.random.seed(1234) idx = date_range(Timestamp('1/1/1900'), freq=offset, periods=N) df = DataFrame(np.random.randn(N, 10), index=idx) self.d = df.to_dict() def time_dict_with_timestamp_offsets(self, offset): DataFrame(self.d)
def _check_offsetfunc_works(self, offset, funcname, dt, expected, normalize=False): if normalize and issubclass(offset, Tick): # normalize=True disallowed for Tick subclasses GH#21427 return offset_s = self._get_offset(offset, normalize=normalize) func = getattr(offset_s, funcname) result = func(dt) assert isinstance(result, Timestamp) assert result == expected result = func(Timestamp(dt)) assert isinstance(result, Timestamp) assert result == expected # see gh-14101 exp_warning = None ts = Timestamp(dt) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname == "apply" or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) assert isinstance(result, Timestamp) if normalize is False: assert result == expected + Nano(5) else: assert result == expected if isinstance(dt, np.datetime64): # test tz when input is datetime or Timestamp return for tz in self.timezones: expected_localize = expected.tz_localize(tz) tz_obj = timezones.maybe_get_tz(tz) dt_tz = conversion.localize_pydatetime(dt, tz_obj) result = func(dt_tz) assert isinstance(result, Timestamp) assert result == expected_localize result = func(Timestamp(dt, tz=tz)) assert isinstance(result, Timestamp) assert result == expected_localize # see gh-14101 exp_warning = None ts = Timestamp(dt, tz=tz) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname == "apply" or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) assert isinstance(result, Timestamp) if normalize is False: assert result == expected_localize + Nano(5) else: assert result == expected_localize
# Test series ---- ser_src = pd.Series(src) ser_low = floor_date(ser_src + offset, unit) ser_hi = ceil_date(ser_src - offset, unit) tm.assert_series_equal(ser_low, ser_src) tm.assert_series_equal(ser_hi, ser_src) @pytest.mark.parametrize("unit", ["S", "D"]) def test_tick(unit): src = pd.DatetimeIndex(["2020-01-02"]) check_floor_ceil(src, Nano(), unit) @pytest.mark.parametrize("offset", [Nano(), Day(), Hour()]) def test_nonperiodic_month(offset): src = pd.DatetimeIndex(["2020-02-01"]) check_floor_ceil(src, offset, "MS") @pytest.mark.parametrize("offset", [Nano(), Day(), Hour()]) def test_floor_nonperiodic_month_end(offset): src = pd.DatetimeIndex(["2020-01-31"]) check_floor_ceil(src, offset, "M") @pytest.mark.parametrize("offset", [Nano(), Day(), Hour(), MonthEnd()]) def test_floor_nonperiodic_year(offset): src = pd.DatetimeIndex(["2020-01-01"]) check_floor_ceil(src, offset, "AS")
def test_Nanosecond(): timestamp = Timestamp(datetime(2010, 1, 1)) assert_offset_equal(Nano(), timestamp, timestamp + np.timedelta64(1, "ns")) assert_offset_equal(Nano(-1), timestamp + np.timedelta64(1, "ns"), timestamp) assert_offset_equal(2 * Nano(), timestamp, timestamp + np.timedelta64(2, "ns")) assert_offset_equal(-1 * Nano(), timestamp + np.timedelta64(1, "ns"), timestamp) assert Nano(3) + Nano(2) == Nano(5) assert Nano(3) - Nano(2) == Nano() # GH9284 assert Nano(1) + Nano(10) == Nano(11) assert Nano(5) + Micro(1) == Nano(1005) assert Micro(5) + Nano(1) == Nano(5001)
def test_tick(unit): src = pd.DatetimeIndex(["2020-01-02"]) check_floor_ceil(src, Nano(), unit)
def get_period_alias(offset_str: str) -> Optional[str]: """ Alias to closest period strings BQ->Q etc. """ return _offset_to_period_map.get(offset_str, None) _name_to_offset_map = { "days": Day(1), "hours": Hour(1), "minutes": Minute(1), "seconds": Second(1), "milliseconds": Milli(1), "microseconds": Micro(1), "nanoseconds": Nano(1), } def to_offset(freq) -> Optional[DateOffset]: """ Return DateOffset object from string or tuple representation or datetime.timedelta object. Parameters ---------- freq : str, tuple, datetime.timedelta, DateOffset or None Returns ------- DateOffset
'BAS': 'BAS-JAN', # BYearBegin(month=1), 'Min': 'T', 'min': 'T', 'ms': 'L', 'us': 'U', 'ns': 'N' } _name_to_offset_map = { 'days': Day(1), 'hours': Hour(1), 'minutes': Minute(1), 'seconds': Second(1), 'milliseconds': Milli(1), 'microseconds': Micro(1), 'nanoseconds': Nano(1) } _INVALID_FREQ_ERROR = "Invalid frequency: {0}" def to_offset(freqstr): """ Return DateOffset object from string representation or Timedelta object Examples -------- >>> to_offset('5Min') Minute(5) """
'BQS-NOV': BQuarterBegin(startingMonth=11), 'BQS-DEC': BQuarterBegin(startingMonth=12), # Weekly 'W-MON': Week(weekday=0), 'W-TUE': Week(weekday=1), 'W-WED': Week(weekday=2), 'W-THU': Week(weekday=3), 'W-FRI': Week(weekday=4), 'W-SAT': Week(weekday=5), 'W-SUN': Week(weekday=6), } if not _np_version_under1p7: _offset_map['N'] = Nano() _offset_to_period_map = { 'WEEKDAY': 'D', 'EOM': 'M', 'BM': 'M', 'BQS': 'Q', 'QS': 'Q', 'BQ': 'Q', 'BA': 'A', 'AS': 'A', 'BAS': 'A', 'MS': 'M', 'D': 'D', 'C': 'C', 'B': 'B',
def _parsed_string_to_bounds(self, reso, parsed): """ Calculate datetime bounds for parsed time string and its resolution. Parameters ---------- reso : Resolution Resolution provided by parsed string. parsed : datetime Datetime from parsed string. Returns ------- lower, upper: pd.Timestamp """ valid_resos = { "year", "month", "quarter", "day", "hour", "minute", "second", "minute", "second", "microsecond", } if reso not in valid_resos: raise KeyError if reso == "year": start = Timestamp(parsed.year, 1, 1) end = Timestamp(parsed.year, 12, 31, 23, 59, 59, 999999) elif reso == "month": d = ccalendar.get_days_in_month(parsed.year, parsed.month) start = Timestamp(parsed.year, parsed.month, 1) end = Timestamp(parsed.year, parsed.month, d, 23, 59, 59, 999999) elif reso == "quarter": qe = (((parsed.month - 1) + 2) % 12) + 1 # two months ahead d = ccalendar.get_days_in_month(parsed.year, qe) # at end of month start = Timestamp(parsed.year, parsed.month, 1) end = Timestamp(parsed.year, qe, d, 23, 59, 59, 999999) elif reso == "day": start = Timestamp(parsed.year, parsed.month, parsed.day) end = start + timedelta(days=1) - Nano(1) elif reso == "hour": start = Timestamp(parsed.year, parsed.month, parsed.day, parsed.hour) end = start + timedelta(hours=1) - Nano(1) elif reso == "minute": start = Timestamp(parsed.year, parsed.month, parsed.day, parsed.hour, parsed.minute) end = start + timedelta(minutes=1) - Nano(1) elif reso == "second": start = Timestamp( parsed.year, parsed.month, parsed.day, parsed.hour, parsed.minute, parsed.second, ) end = start + timedelta(seconds=1) - Nano(1) elif reso == "microsecond": start = Timestamp( parsed.year, parsed.month, parsed.day, parsed.hour, parsed.minute, parsed.second, parsed.microsecond, ) end = start + timedelta(microseconds=1) - Nano(1) # GH 24076 # If an incoming date string contained a UTC offset, need to localize # the parsed date to this offset first before aligning with the index's # timezone if parsed.tzinfo is not None: if self.tz is None: raise ValueError( "The index must be timezone aware when indexing " "with a date string with a UTC offset") start = start.tz_localize(parsed.tzinfo).tz_convert(self.tz) end = end.tz_localize(parsed.tzinfo).tz_convert(self.tz) elif self.tz is not None: start = start.tz_localize(self.tz) end = end.tz_localize(self.tz) return start, end
def test_period_floor_tick(unit): src = pd.DatetimeIndex(["2020-01-02"]) res = floor_date((src + Nano()).to_period("ns"), unit) tm.assert_index_equal(res, src.to_period(unit))
def get_window_bounds( self, num_values: int = 0, min_periods: Optional[int] = None, center: Optional[bool] = None, closed: Optional[str] = None, ) -> Tuple[np.ndarray, np.ndarray]: # if windows is variable, default is 'right', otherwise default is 'both' if closed is None: closed = "right" if self.index is not None else "both" right_closed = closed in ["right", "both"] left_closed = closed in ["left", "both"] if self.index[num_values - 1] < self.index[0]: index_growth_sign = -1 else: index_growth_sign = 1 start = np.empty(num_values, dtype="int64") start.fill(-1) end = np.empty(num_values, dtype="int64") end.fill(-1) start[0] = 0 # right endpoint is closed if right_closed: end[0] = 1 # right endpoint is open else: end[0] = 0 # start is start of slice interval (including) # end is end of slice interval (not including) for i in range(1, num_values): end_bound = self.index[i] start_bound = self.index[i] - index_growth_sign * self.offset # left endpoint is closed if left_closed: start_bound -= Nano(1) # advance the start bound until we are # within the constraint start[i] = i for j in range(start[i - 1], i): if (self.index[j] - start_bound) * index_growth_sign > timedelta(0): start[i] = j break # end bound is previous end # or current index if (self.index[end[i - 1]] - end_bound) * index_growth_sign <= timedelta(0): end[i] = i + 1 else: end[i] = end[i - 1] # right endpoint is open if not right_closed: end[i] -= 1 return start, end
def _check_offsetfunc_works(self, offset, funcname, dt, expected, normalize=False): if normalize and issubclass(offset, Tick): # normalize=True disallowed for Tick subclasses GH#21427 return offset_s = self._get_offset(offset, normalize=normalize) func = getattr(offset_s, funcname) result = func(dt) assert isinstance(result, Timestamp) assert result == expected result = func(Timestamp(dt)) assert isinstance(result, Timestamp) assert result == expected # see gh-14101 exp_warning = None ts = Timestamp(dt) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname in ["apply", "_apply"] or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) if exp_warning is None and funcname == "_apply": # GH#44522 # Check in this particular case to avoid headaches with # testing for multiple warnings produced by the same call. with tm.assert_produces_warning(FutureWarning, match="apply is deprecated"): res2 = offset_s.apply(ts) assert type(res2) is type(result) assert res2 == result assert isinstance(result, Timestamp) if normalize is False: assert result == expected + Nano(5) else: assert result == expected if isinstance(dt, np.datetime64): # test tz when input is datetime or Timestamp return for tz in self.timezones: expected_localize = expected.tz_localize(tz) tz_obj = timezones.maybe_get_tz(tz) dt_tz = conversion.localize_pydatetime(dt, tz_obj) result = func(dt_tz) assert isinstance(result, Timestamp) assert result == expected_localize result = func(Timestamp(dt, tz=tz)) assert isinstance(result, Timestamp) assert result == expected_localize # see gh-14101 exp_warning = None ts = Timestamp(dt, tz=tz) + Nano(5) if (type(offset_s).__name__ == "DateOffset" and (funcname in ["apply", "_apply"] or normalize) and ts.nanosecond > 0): exp_warning = UserWarning # test nanosecond is preserved with tm.assert_produces_warning(exp_warning): result = func(ts) assert isinstance(result, Timestamp) if normalize is False: assert result == expected_localize + Nano(5) else: assert result == expected_localize