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
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2datetimelike delegation
3"""
4from __future__ import annotations
6from typing import TYPE_CHECKING
7import warnings
9import numpy as np
11from pandas.util._exceptions import find_stack_level
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
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
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 )
47class Properties(PandasDelegate, PandasObject, NoNewAttributesMixin):
48 _hidden_attrs = PandasObject._hidden_attrs | {
49 "orig",
50 "name",
51 }
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 )
59 self._parent = data
60 self.orig = orig
61 self.name = getattr(data, "name", None)
62 self._freeze()
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)
69 elif is_datetime64tz_dtype(data.dtype):
70 return DatetimeIndex(data, copy=False, name=self.name)
72 elif is_timedelta64_dtype(data.dtype):
73 return TimedeltaIndex(data, copy=False, name=self.name)
75 elif is_period_dtype(data.dtype):
76 return PeriodArray(data, copy=False)
78 raise TypeError(
79 f"cannot convert an object of type {type(data)} to a datetimelike index"
80 )
82 def _delegate_property_get(self, name):
83 from pandas import Series
85 values = self._get_values()
87 result = getattr(values, name)
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
96 result = np.asarray(result)
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)
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 )
112 return result
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 )
120 def _delegate_method(self, name, *args, **kwargs):
121 from pandas import Series
123 values = self._get_values()
125 method = getattr(values, name)
126 result = method(*args, **kwargs)
128 if not is_list_like(result):
129 return result
131 result = Series(result, index=self._parent.index, name=self.name).__finalize__(
132 self._parent
133 )
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 )
142 return result
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.
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
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
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
193 Returns a Series indexed like the original Series.
194 Raises TypeError if the Series does not contain datetimelike values.
195 """
197 def to_pydatetime(self) -> np.ndarray:
198 """
199 Return the data as an array of :class:`datetime.datetime` objects.
201 Timezone information is retained if present.
203 .. warning::
205 Python's datetime uses microsecond resolution, which is lower than
206 pandas (nanosecond). The values are truncated.
208 Returns
209 -------
210 numpy.ndarray
211 Object dtype array containing native Python datetime objects.
213 See Also
214 --------
215 datetime.datetime : Standard library value for a datetime.
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]
225 >>> s.dt.to_pydatetime()
226 array([datetime.datetime(2018, 3, 10, 0, 0),
227 datetime.datetime(2018, 3, 11, 0, 0)], dtype=object)
229 pandas' nanosecond precision is truncated to microseconds.
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]
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()
243 @property
244 def freq(self):
245 return self._get_values().inferred_freq
247 def isocalendar(self) -> DataFrame:
248 """
249 Calculate year, week, and day according to the ISO 8601 standard.
251 .. versionadded:: 1.1.0
253 Returns
254 -------
255 DataFrame
256 With columns year, week and day.
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.
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)
279 @property
280 def weekofyear(self):
281 """
282 The week ordinal of the year according to the ISO 8601 standard.
284 .. deprecated:: 1.1.0
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")
302 week = weekofyear
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.
317 Returns a Series indexed like the original Series.
318 Raises TypeError if the Series does not contain datetimelike values.
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 """
337 def to_pytimedelta(self) -> np.ndarray:
338 """
339 Return an array of native :class:`datetime.timedelta` objects.
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.
346 Returns
347 -------
348 numpy.ndarray
349 Array of 1D containing data with `datetime.timedelta` type.
351 See Also
352 --------
353 datetime.timedelta : A duration expressing the difference
354 between two date, time, or datetime.
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]
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()
374 @property
375 def components(self):
376 """
377 Return a Dataframe of the components of the Timedeltas.
379 Returns
380 -------
381 DataFrame
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 )
407 @property
408 def freq(self):
409 return self._get_values().inferred_freq
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.
422 Returns a Series indexed like the original Series.
423 Raises TypeError if the Series does not contain datetimelike values.
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
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
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 """
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.
488 if not isinstance(data, ABCSeries):
489 raise TypeError(
490 f"cannot convert an object of type {type(data)} to a datetimelike index"
491 )
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 )
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)
512 raise AttributeError("Can only use .dt accessor with datetimelike values")