def test_array_of_dt64_nat_raises(self): # GH#39462 nat = np.datetime64("NaT", "ns") arr = np.array([nat], dtype=object) # TODO: should be TypeError? msg = "Invalid type for timedelta scalar" with pytest.raises(ValueError, match=msg): TimedeltaIndex(arr) with pytest.raises(ValueError, match=msg): TimedeltaArray._from_sequence(arr) with pytest.raises(ValueError, match=msg): sequence_to_td64ns(arr)
def __new__(cls, data=None, unit=None, freq=None, start=None, end=None, periods=None, closed=None, dtype=_TD_DTYPE, copy=False, name=None, verify_integrity=None): if verify_integrity is not None: warnings.warn("The 'verify_integrity' argument is deprecated, " "will be removed in a future version.", FutureWarning, stacklevel=2) else: verify_integrity = True if data is None: freq, freq_infer = dtl.maybe_infer_freq(freq) warnings.warn("Creating a TimedeltaIndex by passing range " "endpoints is deprecated. Use " "`pandas.timedelta_range` instead.", FutureWarning, stacklevel=2) result = TimedeltaArray._generate_range(start, end, periods, freq, closed=closed) return cls._simple_new(result._data, freq=freq, name=name) if is_scalar(data): raise TypeError('{cls}() must be called with a ' 'collection of some kind, {data} was passed' .format(cls=cls.__name__, data=repr(data))) if unit in {'Y', 'y', 'M'}: warnings.warn("M and Y units are deprecated and " "will be removed in a future version.", FutureWarning, stacklevel=2) if isinstance(data, TimedeltaArray): if copy: data = data.copy() return cls._simple_new(data, name=name, freq=freq) if (isinstance(data, TimedeltaIndex) and freq is None and name is None): if copy: return data.copy() else: return data._shallow_copy() # - Cases checked above all return/raise before reaching here - # tdarr = TimedeltaArray._from_sequence(data, freq=freq, unit=unit, dtype=dtype, copy=copy) return cls._simple_new(tdarr._data, freq=tdarr.freq, name=name)
def _simple_new(cls, values, name=None, freq=None, dtype=_TD_DTYPE): # `dtype` is passed by _shallow_copy in corner cases, should always # be timedelta64[ns] if present if not isinstance(values, TimedeltaArray): values = TimedeltaArray._simple_new(values, dtype=dtype, freq=freq) assert isinstance(values, TimedeltaArray), type(values) assert dtype == _TD_DTYPE, dtype assert values.dtype == 'm8[ns]', values.dtype freq = to_offset(freq) tdarr = TimedeltaArray._simple_new(values, freq=freq) result = object.__new__(cls) result._data = tdarr result.name = name # For groupby perf. See note in indexes/base about _index_data result._index_data = tdarr._data result._reset_identity() return result
def test_infer_from_tdi_mismatch(self): # GH#23539 # fast-path for invalidating a frequency if the passed data already # has one and it does not match the `freq` input tdi = timedelta_range("1 second", periods=100, freq="1s") msg = ("Inferred frequency .* from passed values does " "not conform to passed frequency") with pytest.raises(ValueError, match=msg): TimedeltaIndex(tdi, freq="D") with pytest.raises(ValueError, match=msg): # GH#23789 TimedeltaArray(tdi, freq="D") with pytest.raises(ValueError, match=msg): TimedeltaIndex(tdi._data, freq="D") with pytest.raises(ValueError, match=msg): TimedeltaArray(tdi._data, freq="D")
def _simple_new(cls, values, name=None, freq=None, dtype=_TD_DTYPE): # `dtype` is passed by _shallow_copy in corner cases, should always # be timedelta64[ns] if present if not isinstance(values, TimedeltaArray): values = TimedeltaArray._simple_new(values, dtype=dtype, freq=freq) else: if freq is None: freq = values.freq assert isinstance(values, TimedeltaArray), type(values) assert dtype == _TD_DTYPE, dtype assert values.dtype == 'm8[ns]', values.dtype tdarr = TimedeltaArray._simple_new(values._data, freq=freq) result = object.__new__(cls) result._data = tdarr result.name = name # For groupby perf. See note in indexes/base about _index_data result._index_data = tdarr._data result._reset_identity() return result
def test_explicit_none_freq(self): # Explicitly passing freq=None is respected tdi = timedelta_range(1, periods=5) assert tdi.freq is not None result = TimedeltaIndex(tdi, freq=None) assert result.freq is None result = TimedeltaIndex(tdi._data, freq=None) assert result.freq is None tda = TimedeltaArray(tdi, freq=None) assert tda.freq is None
def __new__( cls, data=None, unit=None, freq=lib.no_default, closed=None, dtype=TD64NS_DTYPE, copy=False, name=None, ): name = maybe_extract_name(name, data, cls) if is_scalar(data): raise TypeError( f"{cls.__name__}() must be called with a " f"collection of some kind, {repr(data)} was passed") if unit in {"Y", "y", "M"}: raise ValueError( "Units 'M', 'Y', and 'y' are no longer supported, as they do not " "represent unambiguous timedelta values durations.") if isinstance(data, TimedeltaArray) and freq is lib.no_default: if copy: data = data.copy() return cls._simple_new(data, name=name) if isinstance( data, TimedeltaIndex) and freq is lib.no_default and name is None: if copy: return data.copy() else: return data._shallow_copy() # - Cases checked above all return/raise before reaching here - # tdarr = TimedeltaArray._from_sequence_not_strict(data, freq=freq, unit=unit, dtype=dtype, copy=copy) return cls._simple_new(tdarr, name=name)
def __new__( cls, data=None, unit=None, freq=None, closed=None, dtype=_TD_DTYPE, copy=False, name=None, ): if is_scalar(data): raise TypeError( "{cls}() must be called with a " "collection of some kind, {data} was passed".format( cls=cls.__name__, data=repr(data) ) ) if unit in {"Y", "y", "M"}: raise ValueError( "Units 'M' and 'Y' are no longer supported, as they do not " "represent unambiguous timedelta values durations." ) if isinstance(data, TimedeltaArray): if copy: data = data.copy() return cls._simple_new(data, name=name, freq=freq) if isinstance(data, TimedeltaIndex) and freq is None and name is None: if copy: return data.copy() else: return data._shallow_copy() # - Cases checked above all return/raise before reaching here - # tdarr = TimedeltaArray._from_sequence( data, freq=freq, unit=unit, dtype=dtype, copy=copy ) return cls._simple_new(tdarr._data, freq=tdarr.freq, name=name)
def __new__( cls, data=None, unit=None, freq=lib.no_default, closed=None, dtype=TD64NS_DTYPE, copy=False, name=None, ): name = maybe_extract_name(name, data, cls) if is_scalar(data): raise cls._scalar_data_error(data) if unit in {"Y", "y", "M"}: raise ValueError( "Units 'M', 'Y', and 'y' are no longer supported, as they do not " "represent unambiguous timedelta values durations.") # FIXME: need to check for dtype/data match if isinstance(data, TimedeltaArray) and freq is lib.no_default: if copy: data = data.copy() return cls._simple_new(data, name=name) if isinstance( data, TimedeltaIndex) and freq is lib.no_default and name is None: if copy: return data.copy() else: return data._view() # - Cases checked above all return/raise before reaching here - # tdarr = TimedeltaArray._from_sequence_not_strict(data, freq=freq, unit=unit, dtype=dtype, copy=copy) return cls._simple_new(tdarr, name=name)
def timedelta_range(start=None, end=None, periods=None, freq=None, name=None, closed=None) -> TimedeltaIndex: """ Return a fixed frequency TimedeltaIndex, with day as the default frequency. Parameters ---------- start : str or timedelta-like, default None Left bound for generating timedeltas. end : str or timedelta-like, default None Right bound for generating timedeltas. periods : int, default None Number of periods to generate. freq : str or DateOffset, default 'D' Frequency strings can have multiples, e.g. '5H'. name : str, default None Name of the resulting TimedeltaIndex. closed : str, default None Make the interval closed with respect to the given frequency to the 'left', 'right', or both sides (None). Returns ------- rng : TimedeltaIndex Notes ----- Of the four parameters ``start``, ``end``, ``periods``, and ``freq``, exactly three must be specified. If ``freq`` is omitted, the resulting ``TimedeltaIndex`` will have ``periods`` linearly spaced elements between ``start`` and ``end`` (closed on both sides). To learn more about the frequency strings, please see `this link <https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases>`__. Examples -------- >>> pd.timedelta_range(start='1 day', periods=4) TimedeltaIndex(['1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq='D') The ``closed`` parameter specifies which endpoint is included. The default behavior is to include both endpoints. >>> pd.timedelta_range(start='1 day', periods=4, closed='right') TimedeltaIndex(['2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq='D') The ``freq`` parameter specifies the frequency of the TimedeltaIndex. Only fixed frequencies can be passed, non-fixed frequencies such as 'M' (month end) will raise. >>> pd.timedelta_range(start='1 day', end='2 days', freq='6H') TimedeltaIndex(['1 days 00:00:00', '1 days 06:00:00', '1 days 12:00:00', '1 days 18:00:00', '2 days 00:00:00'], dtype='timedelta64[ns]', freq='6H') Specify ``start``, ``end``, and ``periods``; the frequency is generated automatically (linearly spaced). >>> pd.timedelta_range(start='1 day', end='5 days', periods=4) TimedeltaIndex(['1 days 00:00:00', '2 days 08:00:00', '3 days 16:00:00', '5 days 00:00:00'], dtype='timedelta64[ns]', freq='32H') """ if freq is None and com.any_none(periods, start, end): freq = "D" freq, freq_infer = dtl.maybe_infer_freq(freq) tdarr = TimedeltaArray._generate_range(start, end, periods, freq, closed=closed) return TimedeltaIndex._simple_new(tdarr, name=name)
def timedelta_range(start=None, end=None, periods=None, freq=None, name=None, closed=None): """ Return a fixed frequency TimedeltaIndex, with day as the default frequency Parameters ---------- start : string or timedelta-like, default None Left bound for generating timedeltas end : string or timedelta-like, default None Right bound for generating timedeltas periods : integer, default None Number of periods to generate freq : string or DateOffset, default 'D' Frequency strings can have multiples, e.g. '5H' name : string, default None Name of the resulting TimedeltaIndex closed : string, default None Make the interval closed with respect to the given frequency to the 'left', 'right', or both sides (None) Returns ------- rng : TimedeltaIndex Notes ----- Of the four parameters ``start``, ``end``, ``periods``, and ``freq``, exactly three must be specified. If ``freq`` is omitted, the resulting ``TimedeltaIndex`` will have ``periods`` linearly spaced elements between ``start`` and ``end`` (closed on both sides). To learn more about the frequency strings, please see `this link <http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases>`__. Examples -------- >>> pd.timedelta_range(start='1 day', periods=4) TimedeltaIndex(['1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq='D') The ``closed`` parameter specifies which endpoint is included. The default behavior is to include both endpoints. >>> pd.timedelta_range(start='1 day', periods=4, closed='right') TimedeltaIndex(['2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq='D') The ``freq`` parameter specifies the frequency of the TimedeltaIndex. Only fixed frequencies can be passed, non-fixed frequencies such as 'M' (month end) will raise. >>> pd.timedelta_range(start='1 day', end='2 days', freq='6H') TimedeltaIndex(['1 days 00:00:00', '1 days 06:00:00', '1 days 12:00:00', '1 days 18:00:00', '2 days 00:00:00'], dtype='timedelta64[ns]', freq='6H') Specify ``start``, ``end``, and ``periods``; the frequency is generated automatically (linearly spaced). >>> pd.timedelta_range(start='1 day', end='5 days', periods=4) TimedeltaIndex(['1 days 00:00:00', '2 days 08:00:00', '3 days 16:00:00', '5 days 00:00:00'], dtype='timedelta64[ns]', freq=None) """ if freq is None and com._any_none(periods, start, end): freq = 'D' freq, freq_infer = dtl.maybe_infer_freq(freq) tdarr = TimedeltaArray._generate_range(start, end, periods, freq, closed=closed) return TimedeltaIndex._simple_new(tdarr._data, freq=tdarr.freq, name=name)