Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pandas/core/indexes/timedeltas.py: 45%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

69 statements  

1""" implement the TimedeltaIndex """ 

2from __future__ import annotations 

3 

4from pandas._libs import ( 

5 index as libindex, 

6 lib, 

7) 

8from pandas._libs.tslibs import ( 

9 Resolution, 

10 Timedelta, 

11 to_offset, 

12) 

13from pandas._typing import DtypeObj 

14 

15from pandas.core.dtypes.common import ( 

16 is_dtype_equal, 

17 is_scalar, 

18 is_timedelta64_dtype, 

19) 

20from pandas.core.dtypes.generic import ABCSeries 

21 

22from pandas.core.arrays import datetimelike as dtl 

23from pandas.core.arrays.timedeltas import TimedeltaArray 

24import pandas.core.common as com 

25from pandas.core.indexes.base import ( 

26 Index, 

27 maybe_extract_name, 

28) 

29from pandas.core.indexes.datetimelike import DatetimeTimedeltaMixin 

30from pandas.core.indexes.extension import inherit_names 

31 

32 

33@inherit_names( 

34 ["__neg__", "__pos__", "__abs__", "total_seconds", "round", "floor", "ceil"] 

35 + TimedeltaArray._field_ops, 

36 TimedeltaArray, 

37 wrap=True, 

38) 

39@inherit_names( 

40 [ 

41 "components", 

42 "to_pytimedelta", 

43 "sum", 

44 "std", 

45 "median", 

46 "_format_native_types", 

47 ], 

48 TimedeltaArray, 

49) 

50class TimedeltaIndex(DatetimeTimedeltaMixin): 

51 """ 

52 Immutable Index of timedelta64 data. 

53 

54 Represented internally as int64, and scalars returned Timedelta objects. 

55 

56 Parameters 

57 ---------- 

58 data : array-like (1-dimensional), optional 

59 Optional timedelta-like data to construct index with. 

60 unit : unit of the arg (D,h,m,s,ms,us,ns) denote the unit, optional 

61 Which is an integer/float number. 

62 freq : str or pandas offset object, optional 

63 One of pandas date offset strings or corresponding objects. The string 

64 'infer' can be passed in order to set the frequency of the index as the 

65 inferred frequency upon creation. 

66 copy : bool 

67 Make a copy of input ndarray. 

68 name : object 

69 Name to be stored in the index. 

70 

71 Attributes 

72 ---------- 

73 days 

74 seconds 

75 microseconds 

76 nanoseconds 

77 components 

78 inferred_freq 

79 

80 Methods 

81 ------- 

82 to_pytimedelta 

83 to_series 

84 round 

85 floor 

86 ceil 

87 to_frame 

88 mean 

89 

90 See Also 

91 -------- 

92 Index : The base pandas Index type. 

93 Timedelta : Represents a duration between two dates or times. 

94 DatetimeIndex : Index of datetime64 data. 

95 PeriodIndex : Index of Period data. 

96 timedelta_range : Create a fixed-frequency TimedeltaIndex. 

97 

98 Notes 

99 ----- 

100 To learn more about the frequency strings, please see `this link 

101 <https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases>`__. 

102 """ 

103 

104 _typ = "timedeltaindex" 

105 

106 _data_cls = TimedeltaArray 

107 

108 @property 

109 def _engine_type(self) -> type[libindex.TimedeltaEngine]: 

110 return libindex.TimedeltaEngine 

111 

112 _data: TimedeltaArray 

113 

114 # Use base class method instead of DatetimeTimedeltaMixin._get_string_slice 

115 _get_string_slice = Index._get_string_slice 

116 

117 # error: Signature of "_resolution_obj" incompatible with supertype 

118 # "DatetimeIndexOpsMixin" 

119 @property 

120 def _resolution_obj(self) -> Resolution | None: # type: ignore[override] 

121 return self._data._resolution_obj 

122 

123 # ------------------------------------------------------------------- 

124 # Constructors 

125 

126 def __new__( 

127 cls, 

128 data=None, 

129 unit=None, 

130 freq=lib.no_default, 

131 closed=None, 

132 dtype=None, 

133 copy: bool = False, 

134 name=None, 

135 ): 

136 name = maybe_extract_name(name, data, cls) 

137 

138 if is_scalar(data): 

139 cls._raise_scalar_data_error(data) 

140 

141 if unit in {"Y", "y", "M"}: 

142 raise ValueError( 

143 "Units 'M', 'Y', and 'y' are no longer supported, as they do not " 

144 "represent unambiguous timedelta values durations." 

145 ) 

146 

147 if ( 

148 isinstance(data, TimedeltaArray) 

149 and freq is lib.no_default 

150 and (dtype is None or is_dtype_equal(dtype, data.dtype)) 

151 ): 

152 if copy: 

153 data = data.copy() 

154 return cls._simple_new(data, name=name) 

155 

156 if ( 

157 isinstance(data, TimedeltaIndex) 

158 and freq is lib.no_default 

159 and name is None 

160 and (dtype is None or is_dtype_equal(dtype, data.dtype)) 

161 ): 

162 if copy: 

163 return data.copy() 

164 else: 

165 return data._view() 

166 

167 # - Cases checked above all return/raise before reaching here - # 

168 

169 tdarr = TimedeltaArray._from_sequence_not_strict( 

170 data, freq=freq, unit=unit, dtype=dtype, copy=copy 

171 ) 

172 refs = None 

173 if not copy and isinstance(data, (ABCSeries, Index)): 

174 refs = data._references 

175 

176 return cls._simple_new(tdarr, name=name, refs=refs) 

177 

178 # ------------------------------------------------------------------- 

179 

180 def _is_comparable_dtype(self, dtype: DtypeObj) -> bool: 

181 """ 

182 Can we compare values of the given dtype to our own? 

183 """ 

184 return is_timedelta64_dtype(dtype) # aka self._data._is_recognized_dtype 

185 

186 # ------------------------------------------------------------------- 

187 # Indexing Methods 

188 

189 def get_loc(self, key): 

190 """ 

191 Get integer location for requested label 

192 

193 Returns 

194 ------- 

195 loc : int, slice, or ndarray[int] 

196 """ 

197 self._check_indexing_error(key) 

198 

199 try: 

200 key = self._data._validate_scalar(key, unbox=False) 

201 except TypeError as err: 

202 raise KeyError(key) from err 

203 

204 return Index.get_loc(self, key) 

205 

206 def _parse_with_reso(self, label: str): 

207 # the "with_reso" is a no-op for TimedeltaIndex 

208 parsed = Timedelta(label) 

209 return parsed, None 

210 

211 def _parsed_string_to_bounds(self, reso, parsed: Timedelta): 

212 # reso is unused, included to match signature of DTI/PI 

213 lbound = parsed.round(parsed.resolution_string) 

214 rbound = lbound + to_offset(parsed.resolution_string) - Timedelta(1, "ns") 

215 return lbound, rbound 

216 

217 # ------------------------------------------------------------------- 

218 

219 @property 

220 def inferred_type(self) -> str: 

221 return "timedelta64" 

222 

223 

224def timedelta_range( 

225 start=None, 

226 end=None, 

227 periods: int | None = None, 

228 freq=None, 

229 name=None, 

230 closed=None, 

231 *, 

232 unit: str | None = None, 

233) -> TimedeltaIndex: 

234 """ 

235 Return a fixed frequency TimedeltaIndex with day as the default. 

236 

237 Parameters 

238 ---------- 

239 start : str or timedelta-like, default None 

240 Left bound for generating timedeltas. 

241 end : str or timedelta-like, default None 

242 Right bound for generating timedeltas. 

243 periods : int, default None 

244 Number of periods to generate. 

245 freq : str or DateOffset, default 'D' 

246 Frequency strings can have multiples, e.g. '5H'. 

247 name : str, default None 

248 Name of the resulting TimedeltaIndex. 

249 closed : str, default None 

250 Make the interval closed with respect to the given frequency to 

251 the 'left', 'right', or both sides (None). 

252 unit : str, default None 

253 Specify the desired resolution of the result. 

254 

255 .. versionadded:: 2.0.0 

256 

257 Returns 

258 ------- 

259 TimedeltaIndex 

260 

261 Notes 

262 ----- 

263 Of the four parameters ``start``, ``end``, ``periods``, and ``freq``, 

264 exactly three must be specified. If ``freq`` is omitted, the resulting 

265 ``TimedeltaIndex`` will have ``periods`` linearly spaced elements between 

266 ``start`` and ``end`` (closed on both sides). 

267 

268 To learn more about the frequency strings, please see `this link 

269 <https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases>`__. 

270 

271 Examples 

272 -------- 

273 >>> pd.timedelta_range(start='1 day', periods=4) 

274 TimedeltaIndex(['1 days', '2 days', '3 days', '4 days'], 

275 dtype='timedelta64[ns]', freq='D') 

276 

277 The ``closed`` parameter specifies which endpoint is included. The default 

278 behavior is to include both endpoints. 

279 

280 >>> pd.timedelta_range(start='1 day', periods=4, closed='right') 

281 TimedeltaIndex(['2 days', '3 days', '4 days'], 

282 dtype='timedelta64[ns]', freq='D') 

283 

284 The ``freq`` parameter specifies the frequency of the TimedeltaIndex. 

285 Only fixed frequencies can be passed, non-fixed frequencies such as 

286 'M' (month end) will raise. 

287 

288 >>> pd.timedelta_range(start='1 day', end='2 days', freq='6H') 

289 TimedeltaIndex(['1 days 00:00:00', '1 days 06:00:00', '1 days 12:00:00', 

290 '1 days 18:00:00', '2 days 00:00:00'], 

291 dtype='timedelta64[ns]', freq='6H') 

292 

293 Specify ``start``, ``end``, and ``periods``; the frequency is generated 

294 automatically (linearly spaced). 

295 

296 >>> pd.timedelta_range(start='1 day', end='5 days', periods=4) 

297 TimedeltaIndex(['1 days 00:00:00', '2 days 08:00:00', '3 days 16:00:00', 

298 '5 days 00:00:00'], 

299 dtype='timedelta64[ns]', freq=None) 

300 

301 **Specify a unit** 

302 

303 >>> pd.timedelta_range("1 Day", periods=3, freq="100000D", unit="s") 

304 TimedeltaIndex(['1 days 00:00:00', '100001 days 00:00:00', 

305 '200001 days 00:00:00'], 

306 dtype='timedelta64[s]', freq='100000D') 

307 """ 

308 if freq is None and com.any_none(periods, start, end): 

309 freq = "D" 

310 

311 freq, _ = dtl.maybe_infer_freq(freq) 

312 tdarr = TimedeltaArray._generate_range( 

313 start, end, periods, freq, closed=closed, unit=unit 

314 ) 

315 return TimedeltaIndex._simple_new(tdarr, name=name)