Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/pandas/core/indexes/accessors.py: 34%

111 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1""" 

2datetimelike delegation 

3""" 

4from __future__ import annotations 

5 

6from typing import TYPE_CHECKING 

7import warnings 

8 

9import numpy as np 

10 

11from pandas.util._exceptions import find_stack_level 

12 

13from pandas.core.dtypes.common import ( 

14 is_categorical_dtype, 

15 is_datetime64_dtype, 

16 is_datetime64tz_dtype, 

17 is_integer_dtype, 

18 is_list_like, 

19 is_period_dtype, 

20 is_timedelta64_dtype, 

21) 

22from pandas.core.dtypes.generic import ABCSeries 

23 

24from pandas.core.accessor import ( 

25 PandasDelegate, 

26 delegate_names, 

27) 

28from pandas.core.arrays import ( 

29 DatetimeArray, 

30 PeriodArray, 

31 TimedeltaArray, 

32) 

33from pandas.core.base import ( 

34 NoNewAttributesMixin, 

35 PandasObject, 

36) 

37from pandas.core.indexes.datetimes import DatetimeIndex 

38from pandas.core.indexes.timedeltas import TimedeltaIndex 

39 

40if TYPE_CHECKING: 40 ↛ 41line 40 didn't jump to line 41, because the condition on line 40 was never true

41 from pandas import ( 

42 DataFrame, 

43 Series, 

44 ) 

45 

46 

47class Properties(PandasDelegate, PandasObject, NoNewAttributesMixin): 

48 _hidden_attrs = PandasObject._hidden_attrs | { 

49 "orig", 

50 "name", 

51 } 

52 

53 def __init__(self, data: Series, orig) -> None: 

54 if not isinstance(data, ABCSeries): 

55 raise TypeError( 

56 f"cannot convert an object of type {type(data)} to a datetimelike index" 

57 ) 

58 

59 self._parent = data 

60 self.orig = orig 

61 self.name = getattr(data, "name", None) 

62 self._freeze() 

63 

64 def _get_values(self): 

65 data = self._parent 

66 if is_datetime64_dtype(data.dtype): 

67 return DatetimeIndex(data, copy=False, name=self.name) 

68 

69 elif is_datetime64tz_dtype(data.dtype): 

70 return DatetimeIndex(data, copy=False, name=self.name) 

71 

72 elif is_timedelta64_dtype(data.dtype): 

73 return TimedeltaIndex(data, copy=False, name=self.name) 

74 

75 elif is_period_dtype(data.dtype): 

76 return PeriodArray(data, copy=False) 

77 

78 raise TypeError( 

79 f"cannot convert an object of type {type(data)} to a datetimelike index" 

80 ) 

81 

82 def _delegate_property_get(self, name): 

83 from pandas import Series 

84 

85 values = self._get_values() 

86 

87 result = getattr(values, name) 

88 

89 # maybe need to upcast (ints) 

90 if isinstance(result, np.ndarray): 

91 if is_integer_dtype(result): 

92 result = result.astype("int64") 

93 elif not is_list_like(result): 

94 return result 

95 

96 result = np.asarray(result) 

97 

98 if self.orig is not None: 

99 index = self.orig.index 

100 else: 

101 index = self._parent.index 

102 # return the result as a Series, which is by definition a copy 

103 result = Series(result, index=index, name=self.name).__finalize__(self._parent) 

104 

105 # setting this object will show a SettingWithCopyWarning/Error 

106 result._is_copy = ( 

107 "modifications to a property of a datetimelike " 

108 "object are not supported and are discarded. " 

109 "Change values on the original." 

110 ) 

111 

112 return result 

113 

114 def _delegate_property_set(self, name, value, *args, **kwargs): 

115 raise ValueError( 

116 "modifications to a property of a datetimelike object are not supported. " 

117 "Change values on the original." 

118 ) 

119 

120 def _delegate_method(self, name, *args, **kwargs): 

121 from pandas import Series 

122 

123 values = self._get_values() 

124 

125 method = getattr(values, name) 

126 result = method(*args, **kwargs) 

127 

128 if not is_list_like(result): 

129 return result 

130 

131 result = Series(result, index=self._parent.index, name=self.name).__finalize__( 

132 self._parent 

133 ) 

134 

135 # setting this object will show a SettingWithCopyWarning/Error 

136 result._is_copy = ( 

137 "modifications to a method of a datetimelike " 

138 "object are not supported and are discarded. " 

139 "Change values on the original." 

140 ) 

141 

142 return result 

143 

144 

145@delegate_names( 

146 delegate=DatetimeArray, accessors=DatetimeArray._datetimelike_ops, typ="property" 

147) 

148@delegate_names( 

149 delegate=DatetimeArray, accessors=DatetimeArray._datetimelike_methods, typ="method" 

150) 

151class DatetimeProperties(Properties): 

152 """ 

153 Accessor object for datetimelike properties of the Series values. 

154 

155 Examples 

156 -------- 

157 >>> seconds_series = pd.Series(pd.date_range("2000-01-01", periods=3, freq="s")) 

158 >>> seconds_series 

159 0 2000-01-01 00:00:00 

160 1 2000-01-01 00:00:01 

161 2 2000-01-01 00:00:02 

162 dtype: datetime64[ns] 

163 >>> seconds_series.dt.second 

164 0 0 

165 1 1 

166 2 2 

167 dtype: int64 

168 

169 >>> hours_series = pd.Series(pd.date_range("2000-01-01", periods=3, freq="h")) 

170 >>> hours_series 

171 0 2000-01-01 00:00:00 

172 1 2000-01-01 01:00:00 

173 2 2000-01-01 02:00:00 

174 dtype: datetime64[ns] 

175 >>> hours_series.dt.hour 

176 0 0 

177 1 1 

178 2 2 

179 dtype: int64 

180 

181 >>> quarters_series = pd.Series(pd.date_range("2000-01-01", periods=3, freq="q")) 

182 >>> quarters_series 

183 0 2000-03-31 

184 1 2000-06-30 

185 2 2000-09-30 

186 dtype: datetime64[ns] 

187 >>> quarters_series.dt.quarter 

188 0 1 

189 1 2 

190 2 3 

191 dtype: int64 

192 

193 Returns a Series indexed like the original Series. 

194 Raises TypeError if the Series does not contain datetimelike values. 

195 """ 

196 

197 def to_pydatetime(self) -> np.ndarray: 

198 """ 

199 Return the data as an array of :class:`datetime.datetime` objects. 

200 

201 Timezone information is retained if present. 

202 

203 .. warning:: 

204 

205 Python's datetime uses microsecond resolution, which is lower than 

206 pandas (nanosecond). The values are truncated. 

207 

208 Returns 

209 ------- 

210 numpy.ndarray 

211 Object dtype array containing native Python datetime objects. 

212 

213 See Also 

214 -------- 

215 datetime.datetime : Standard library value for a datetime. 

216 

217 Examples 

218 -------- 

219 >>> s = pd.Series(pd.date_range('20180310', periods=2)) 

220 >>> s 

221 0 2018-03-10 

222 1 2018-03-11 

223 dtype: datetime64[ns] 

224 

225 >>> s.dt.to_pydatetime() 

226 array([datetime.datetime(2018, 3, 10, 0, 0), 

227 datetime.datetime(2018, 3, 11, 0, 0)], dtype=object) 

228 

229 pandas' nanosecond precision is truncated to microseconds. 

230 

231 >>> s = pd.Series(pd.date_range('20180310', periods=2, freq='ns')) 

232 >>> s 

233 0 2018-03-10 00:00:00.000000000 

234 1 2018-03-10 00:00:00.000000001 

235 dtype: datetime64[ns] 

236 

237 >>> s.dt.to_pydatetime() 

238 array([datetime.datetime(2018, 3, 10, 0, 0), 

239 datetime.datetime(2018, 3, 10, 0, 0)], dtype=object) 

240 """ 

241 return self._get_values().to_pydatetime() 

242 

243 @property 

244 def freq(self): 

245 return self._get_values().inferred_freq 

246 

247 def isocalendar(self) -> DataFrame: 

248 """ 

249 Calculate year, week, and day according to the ISO 8601 standard. 

250 

251 .. versionadded:: 1.1.0 

252 

253 Returns 

254 ------- 

255 DataFrame 

256 With columns year, week and day. 

257 

258 See Also 

259 -------- 

260 Timestamp.isocalendar : Function return a 3-tuple containing ISO year, 

261 week number, and weekday for the given Timestamp object. 

262 datetime.date.isocalendar : Return a named tuple object with 

263 three components: year, week and weekday. 

264 

265 Examples 

266 -------- 

267 >>> ser = pd.to_datetime(pd.Series(["2010-01-01", pd.NaT])) 

268 >>> ser.dt.isocalendar() 

269 year week day 

270 0 2009 53 5 

271 1 <NA> <NA> <NA> 

272 >>> ser.dt.isocalendar().week 

273 0 53 

274 1 <NA> 

275 Name: week, dtype: UInt32 

276 """ 

277 return self._get_values().isocalendar().set_index(self._parent.index) 

278 

279 @property 

280 def weekofyear(self): 

281 """ 

282 The week ordinal of the year according to the ISO 8601 standard. 

283 

284 .. deprecated:: 1.1.0 

285 

286 Series.dt.weekofyear and Series.dt.week have been deprecated. Please 

287 call :func:`Series.dt.isocalendar` and access the ``week`` column 

288 instead. 

289 """ 

290 warnings.warn( 

291 "Series.dt.weekofyear and Series.dt.week have been deprecated. " 

292 "Please use Series.dt.isocalendar().week instead.", 

293 FutureWarning, 

294 stacklevel=find_stack_level(), 

295 ) 

296 week_series = self.isocalendar().week 

297 week_series.name = self.name 

298 if week_series.hasnans: 

299 return week_series.astype("float64") 

300 return week_series.astype("int64") 

301 

302 week = weekofyear 

303 

304 

305@delegate_names( 

306 delegate=TimedeltaArray, accessors=TimedeltaArray._datetimelike_ops, typ="property" 

307) 

308@delegate_names( 

309 delegate=TimedeltaArray, 

310 accessors=TimedeltaArray._datetimelike_methods, 

311 typ="method", 

312) 

313class TimedeltaProperties(Properties): 

314 """ 

315 Accessor object for datetimelike properties of the Series values. 

316 

317 Returns a Series indexed like the original Series. 

318 Raises TypeError if the Series does not contain datetimelike values. 

319 

320 Examples 

321 -------- 

322 >>> seconds_series = pd.Series( 

323 ... pd.timedelta_range(start="1 second", periods=3, freq="S") 

324 ... ) 

325 >>> seconds_series 

326 0 0 days 00:00:01 

327 1 0 days 00:00:02 

328 2 0 days 00:00:03 

329 dtype: timedelta64[ns] 

330 >>> seconds_series.dt.seconds 

331 0 1 

332 1 2 

333 2 3 

334 dtype: int64 

335 """ 

336 

337 def to_pytimedelta(self) -> np.ndarray: 

338 """ 

339 Return an array of native :class:`datetime.timedelta` objects. 

340 

341 Python's standard `datetime` library uses a different representation 

342 timedelta's. This method converts a Series of pandas Timedeltas 

343 to `datetime.timedelta` format with the same length as the original 

344 Series. 

345 

346 Returns 

347 ------- 

348 numpy.ndarray 

349 Array of 1D containing data with `datetime.timedelta` type. 

350 

351 See Also 

352 -------- 

353 datetime.timedelta : A duration expressing the difference 

354 between two date, time, or datetime. 

355 

356 Examples 

357 -------- 

358 >>> s = pd.Series(pd.to_timedelta(np.arange(5), unit="d")) 

359 >>> s 

360 0 0 days 

361 1 1 days 

362 2 2 days 

363 3 3 days 

364 4 4 days 

365 dtype: timedelta64[ns] 

366 

367 >>> s.dt.to_pytimedelta() 

368 array([datetime.timedelta(0), datetime.timedelta(days=1), 

369 datetime.timedelta(days=2), datetime.timedelta(days=3), 

370 datetime.timedelta(days=4)], dtype=object) 

371 """ 

372 return self._get_values().to_pytimedelta() 

373 

374 @property 

375 def components(self): 

376 """ 

377 Return a Dataframe of the components of the Timedeltas. 

378 

379 Returns 

380 ------- 

381 DataFrame 

382 

383 Examples 

384 -------- 

385 >>> s = pd.Series(pd.to_timedelta(np.arange(5), unit='s')) 

386 >>> s 

387 0 0 days 00:00:00 

388 1 0 days 00:00:01 

389 2 0 days 00:00:02 

390 3 0 days 00:00:03 

391 4 0 days 00:00:04 

392 dtype: timedelta64[ns] 

393 >>> s.dt.components 

394 days hours minutes seconds milliseconds microseconds nanoseconds 

395 0 0 0 0 0 0 0 0 

396 1 0 0 0 1 0 0 0 

397 2 0 0 0 2 0 0 0 

398 3 0 0 0 3 0 0 0 

399 4 0 0 0 4 0 0 0 

400 """ 

401 return ( 

402 self._get_values() 

403 .components.set_index(self._parent.index) 

404 .__finalize__(self._parent) 

405 ) 

406 

407 @property 

408 def freq(self): 

409 return self._get_values().inferred_freq 

410 

411 

412@delegate_names( 

413 delegate=PeriodArray, accessors=PeriodArray._datetimelike_ops, typ="property" 

414) 

415@delegate_names( 

416 delegate=PeriodArray, accessors=PeriodArray._datetimelike_methods, typ="method" 

417) 

418class PeriodProperties(Properties): 

419 """ 

420 Accessor object for datetimelike properties of the Series values. 

421 

422 Returns a Series indexed like the original Series. 

423 Raises TypeError if the Series does not contain datetimelike values. 

424 

425 Examples 

426 -------- 

427 >>> seconds_series = pd.Series( 

428 ... pd.period_range( 

429 ... start="2000-01-01 00:00:00", end="2000-01-01 00:00:03", freq="s" 

430 ... ) 

431 ... ) 

432 >>> seconds_series 

433 0 2000-01-01 00:00:00 

434 1 2000-01-01 00:00:01 

435 2 2000-01-01 00:00:02 

436 3 2000-01-01 00:00:03 

437 dtype: period[S] 

438 >>> seconds_series.dt.second 

439 0 0 

440 1 1 

441 2 2 

442 3 3 

443 dtype: int64 

444 

445 >>> hours_series = pd.Series( 

446 ... pd.period_range(start="2000-01-01 00:00", end="2000-01-01 03:00", freq="h") 

447 ... ) 

448 >>> hours_series 

449 0 2000-01-01 00:00 

450 1 2000-01-01 01:00 

451 2 2000-01-01 02:00 

452 3 2000-01-01 03:00 

453 dtype: period[H] 

454 >>> hours_series.dt.hour 

455 0 0 

456 1 1 

457 2 2 

458 3 3 

459 dtype: int64 

460 

461 >>> quarters_series = pd.Series( 

462 ... pd.period_range(start="2000-01-01", end="2000-12-31", freq="Q-DEC") 

463 ... ) 

464 >>> quarters_series 

465 0 2000Q1 

466 1 2000Q2 

467 2 2000Q3 

468 3 2000Q4 

469 dtype: period[Q-DEC] 

470 >>> quarters_series.dt.quarter 

471 0 1 

472 1 2 

473 2 3 

474 3 4 

475 dtype: int64 

476 """ 

477 

478 

479class CombinedDatetimelikeProperties( 

480 DatetimeProperties, TimedeltaProperties, PeriodProperties 

481): 

482 def __new__(cls, data: Series): 

483 # CombinedDatetimelikeProperties isn't really instantiated. Instead 

484 # we need to choose which parent (datetime or timedelta) is 

485 # appropriate. Since we're checking the dtypes anyway, we'll just 

486 # do all the validation here. 

487 

488 if not isinstance(data, ABCSeries): 

489 raise TypeError( 

490 f"cannot convert an object of type {type(data)} to a datetimelike index" 

491 ) 

492 

493 orig = data if is_categorical_dtype(data.dtype) else None 

494 if orig is not None: 

495 data = data._constructor( 

496 orig.array, 

497 name=orig.name, 

498 copy=False, 

499 dtype=orig._values.categories.dtype, 

500 index=orig.index, 

501 ) 

502 

503 if is_datetime64_dtype(data.dtype): 

504 return DatetimeProperties(data, orig) 

505 elif is_datetime64tz_dtype(data.dtype): 

506 return DatetimeProperties(data, orig) 

507 elif is_timedelta64_dtype(data.dtype): 

508 return TimedeltaProperties(data, orig) 

509 elif is_period_dtype(data.dtype): 

510 return PeriodProperties(data, orig) 

511 

512 raise AttributeError("Can only use .dt accessor with datetimelike values")