Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/pandas/core/indexes/accessors.py : 32%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2datetimelike delegation
3"""
4import numpy as np
6from pandas.core.dtypes.common import (
7 is_categorical_dtype,
8 is_datetime64_dtype,
9 is_datetime64tz_dtype,
10 is_datetime_arraylike,
11 is_integer_dtype,
12 is_list_like,
13 is_period_arraylike,
14 is_timedelta64_dtype,
15)
16from pandas.core.dtypes.generic import ABCSeries
18from pandas.core.accessor import PandasDelegate, delegate_names
19from pandas.core.arrays import DatetimeArray, PeriodArray, TimedeltaArray
20from pandas.core.base import NoNewAttributesMixin, PandasObject
21from pandas.core.indexes.datetimes import DatetimeIndex
22from pandas.core.indexes.timedeltas import TimedeltaIndex
25class Properties(PandasDelegate, PandasObject, NoNewAttributesMixin):
26 def __init__(self, data, orig):
27 if not isinstance(data, ABCSeries):
28 raise TypeError(
29 f"cannot convert an object of type {type(data)} to a datetimelike index"
30 )
32 self._parent = data
33 self.orig = orig
34 self.name = getattr(data, "name", None)
35 self._freeze()
37 def _get_values(self):
38 data = self._parent
39 if is_datetime64_dtype(data.dtype):
40 return DatetimeIndex(data, copy=False, name=self.name)
42 elif is_datetime64tz_dtype(data.dtype):
43 return DatetimeIndex(data, copy=False, name=self.name)
45 elif is_timedelta64_dtype(data.dtype):
46 return TimedeltaIndex(data, copy=False, name=self.name)
48 else:
49 if is_period_arraylike(data):
50 # TODO: use to_period_array
51 return PeriodArray(data, copy=False)
52 if is_datetime_arraylike(data):
53 return DatetimeIndex(data, copy=False, name=self.name)
55 raise TypeError(
56 f"cannot convert an object of type {type(data)} to a datetimelike index"
57 )
59 def _delegate_property_get(self, name):
60 from pandas import Series
62 values = self._get_values()
64 result = getattr(values, name)
66 # maybe need to upcast (ints)
67 if isinstance(result, np.ndarray):
68 if is_integer_dtype(result):
69 result = result.astype("int64")
70 elif not is_list_like(result):
71 return result
73 result = np.asarray(result)
75 if self.orig is not None:
76 index = self.orig.index
77 else:
78 index = self._parent.index
79 # return the result as a Series, which is by definition a copy
80 result = Series(result, index=index, name=self.name)
82 # setting this object will show a SettingWithCopyWarning/Error
83 result._is_copy = (
84 "modifications to a property of a datetimelike "
85 "object are not supported and are discarded. "
86 "Change values on the original."
87 )
89 return result
91 def _delegate_property_set(self, name, value, *args, **kwargs):
92 raise ValueError(
93 "modifications to a property of a datetimelike object are not supported. "
94 "Change values on the original."
95 )
97 def _delegate_method(self, name, *args, **kwargs):
98 from pandas import Series
100 values = self._get_values()
102 method = getattr(values, name)
103 result = method(*args, **kwargs)
105 if not is_list_like(result):
106 return result
108 result = Series(result, index=self._parent.index, name=self.name)
110 # setting this object will show a SettingWithCopyWarning/Error
111 result._is_copy = (
112 "modifications to a method of a datetimelike "
113 "object are not supported and are discarded. "
114 "Change values on the original."
115 )
117 return result
120@delegate_names(
121 delegate=DatetimeArray, accessors=DatetimeArray._datetimelike_ops, typ="property"
122)
123@delegate_names(
124 delegate=DatetimeArray, accessors=DatetimeArray._datetimelike_methods, typ="method"
125)
126class DatetimeProperties(Properties):
127 """
128 Accessor object for datetimelike properties of the Series values.
130 Examples
131 --------
132 >>> s.dt.hour
133 >>> s.dt.second
134 >>> s.dt.quarter
136 Returns a Series indexed like the original Series.
137 Raises TypeError if the Series does not contain datetimelike values.
138 """
140 def to_pydatetime(self):
141 """
142 Return the data as an array of native Python datetime objects.
144 Timezone information is retained if present.
146 .. warning::
148 Python's datetime uses microsecond resolution, which is lower than
149 pandas (nanosecond). The values are truncated.
151 Returns
152 -------
153 numpy.ndarray
154 Object dtype array containing native Python datetime objects.
156 See Also
157 --------
158 datetime.datetime : Standard library value for a datetime.
160 Examples
161 --------
162 >>> s = pd.Series(pd.date_range('20180310', periods=2))
163 >>> s
164 0 2018-03-10
165 1 2018-03-11
166 dtype: datetime64[ns]
168 >>> s.dt.to_pydatetime()
169 array([datetime.datetime(2018, 3, 10, 0, 0),
170 datetime.datetime(2018, 3, 11, 0, 0)], dtype=object)
172 pandas' nanosecond precision is truncated to microseconds.
174 >>> s = pd.Series(pd.date_range('20180310', periods=2, freq='ns'))
175 >>> s
176 0 2018-03-10 00:00:00.000000000
177 1 2018-03-10 00:00:00.000000001
178 dtype: datetime64[ns]
180 >>> s.dt.to_pydatetime()
181 array([datetime.datetime(2018, 3, 10, 0, 0),
182 datetime.datetime(2018, 3, 10, 0, 0)], dtype=object)
183 """
184 return self._get_values().to_pydatetime()
186 @property
187 def freq(self):
188 return self._get_values().inferred_freq
191@delegate_names(
192 delegate=TimedeltaArray, accessors=TimedeltaArray._datetimelike_ops, typ="property"
193)
194@delegate_names(
195 delegate=TimedeltaArray,
196 accessors=TimedeltaArray._datetimelike_methods,
197 typ="method",
198)
199class TimedeltaProperties(Properties):
200 """
201 Accessor object for datetimelike properties of the Series values.
203 Examples
204 --------
205 >>> s.dt.hours
206 >>> s.dt.seconds
208 Returns a Series indexed like the original Series.
209 Raises TypeError if the Series does not contain datetimelike values.
210 """
212 def to_pytimedelta(self):
213 """
214 Return an array of native `datetime.timedelta` objects.
216 Python's standard `datetime` library uses a different representation
217 timedelta's. This method converts a Series of pandas Timedeltas
218 to `datetime.timedelta` format with the same length as the original
219 Series.
221 Returns
222 -------
223 numpy.ndarray
224 Array of 1D containing data with `datetime.timedelta` type.
226 See Also
227 --------
228 datetime.timedelta
230 Examples
231 --------
232 >>> s = pd.Series(pd.to_timedelta(np.arange(5), unit='d'))
233 >>> s
234 0 0 days
235 1 1 days
236 2 2 days
237 3 3 days
238 4 4 days
239 dtype: timedelta64[ns]
241 >>> s.dt.to_pytimedelta()
242 array([datetime.timedelta(0), datetime.timedelta(1),
243 datetime.timedelta(2), datetime.timedelta(3),
244 datetime.timedelta(4)], dtype=object)
245 """
246 return self._get_values().to_pytimedelta()
248 @property
249 def components(self):
250 """
251 Return a Dataframe of the components of the Timedeltas.
253 Returns
254 -------
255 DataFrame
257 Examples
258 --------
259 >>> s = pd.Series(pd.to_timedelta(np.arange(5), unit='s'))
260 >>> s
261 0 00:00:00
262 1 00:00:01
263 2 00:00:02
264 3 00:00:03
265 4 00:00:04
266 dtype: timedelta64[ns]
267 >>> s.dt.components
268 days hours minutes seconds milliseconds microseconds nanoseconds
269 0 0 0 0 0 0 0 0
270 1 0 0 0 1 0 0 0
271 2 0 0 0 2 0 0 0
272 3 0 0 0 3 0 0 0
273 4 0 0 0 4 0 0 0
274 """ # noqa: E501
275 return self._get_values().components.set_index(self._parent.index)
277 @property
278 def freq(self):
279 return self._get_values().inferred_freq
282@delegate_names(
283 delegate=PeriodArray, accessors=PeriodArray._datetimelike_ops, typ="property"
284)
285@delegate_names(
286 delegate=PeriodArray, accessors=PeriodArray._datetimelike_methods, typ="method"
287)
288class PeriodProperties(Properties):
289 """
290 Accessor object for datetimelike properties of the Series values.
292 Examples
293 --------
294 >>> s.dt.hour
295 >>> s.dt.second
296 >>> s.dt.quarter
298 Returns a Series indexed like the original Series.
299 Raises TypeError if the Series does not contain datetimelike values.
300 """
303class CombinedDatetimelikeProperties(
304 DatetimeProperties, TimedeltaProperties, PeriodProperties
305):
306 def __new__(cls, data):
307 # CombinedDatetimelikeProperties isn't really instantiated. Instead
308 # we need to choose which parent (datetime or timedelta) is
309 # appropriate. Since we're checking the dtypes anyway, we'll just
310 # do all the validation here.
311 from pandas import Series
313 if not isinstance(data, ABCSeries):
314 raise TypeError(
315 f"cannot convert an object of type {type(data)} to a datetimelike index"
316 )
318 orig = data if is_categorical_dtype(data) else None
319 if orig is not None:
320 data = Series(
321 orig.array,
322 name=orig.name,
323 copy=False,
324 dtype=orig.values.categories.dtype,
325 )
327 if is_datetime64_dtype(data.dtype):
328 return DatetimeProperties(data, orig)
329 elif is_datetime64tz_dtype(data.dtype):
330 return DatetimeProperties(data, orig)
331 elif is_timedelta64_dtype(data.dtype):
332 return TimedeltaProperties(data, orig)
333 elif is_period_arraylike(data):
334 return PeriodProperties(data, orig)
335 elif is_datetime_arraylike(data):
336 return DatetimeProperties(data, orig)
338 raise AttributeError("Can only use .dt accessor with datetimelike values")