def _partial_date_slice(self, reso: str, parsed: datetime, use_lhs: bool = True, use_rhs: bool = True): """ Parameters ---------- reso : str use_lhs : bool, default True use_rhs : bool, default True """ is_monotonic = self.is_monotonic if (is_monotonic and reso in ["day", "hour", "minute", "second"] and self._resolution >= Resolution.get_reso(reso)): # These resolution/monotonicity validations came from GH3931, # GH3452 and GH2369. # See also GH14826 raise KeyError if reso == "microsecond": # _partial_date_slice doesn't allow microsecond resolution, but # _parsed_string_to_bounds allows it. raise KeyError t1, t2 = self._parsed_string_to_bounds(reso, parsed) stamps = self.asi8 if is_monotonic: # we are out of range if len(stamps) and ( (use_lhs and t1.value < stamps[0] and t2.value < stamps[0]) or ((use_rhs and t1.value > stamps[-1] and t2.value > stamps[-1]))): raise KeyError # a monotonic (sorted) series can be sliced # Use asi8.searchsorted to avoid re-validating left = stamps.searchsorted(t1.value, side="left") if use_lhs else None right = stamps.searchsorted(t2.value, side="right") if use_rhs else None return slice(left, right) lhs_mask = (stamps >= t1.value) if use_lhs else True rhs_mask = (stamps <= t2.value) if use_rhs else True # try to find a the dates return (lhs_mask & rhs_mask).nonzero()[0]
def _validate_partial_date_slice(self, reso: str): if (self.is_monotonic and reso in ["day", "hour", "minute", "second"] and self._resolution >= Resolution.get_reso(reso)): # These resolution/monotonicity validations came from GH3931, # GH3452 and GH2369. # See also GH14826 raise KeyError if reso == "microsecond": # _partial_date_slice doesn't allow microsecond resolution, but # _parsed_string_to_bounds allows it. raise KeyError
def _parsed_string_to_bounds(self, reso: str, parsed: datetime): """ Calculate datetime bounds for parsed time string and its resolution. Parameters ---------- reso : str 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 grp = Resolution.get_freq_group(reso) per = Period(parsed, freq=(grp, 1)) start, end = per.start_time, per.end_time # 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 _resolution(self): from pandas.tseries.frequencies import Resolution return Resolution.get_reso_from_freq(self.freqstr)
def resolution(self): """ Returns day, hour, minute, second, millisecond or microsecond """ return Resolution.get_str(self._resolution)