-
- Notifications
You must be signed in to change notification settings - Fork 19.3k
REF: Make PeriodArray an ExtensionArray #22862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
eaadcbc a05928a 3c0d9ee 63fc3fa 7d5d71c e5caac6 c194407 eb4506b 1b9fd7a 0fa0ed1 3247ea8 c162cdd 611d378 fb2ff82 25a380f 1b2c4ec d04293e eacad39 70cd3b8 9b22889 87d289a 6369c7f 01551f0 0437940 42ab137 298390f 23e5cfc 9d17fd2 959cd72 b66f617 5669675 2c0311c 012be1c c3a96d0 67faabc ff7c06c c2d57bd fbde770 1c4bbe7 b395c90 d68a5c5 0c7b704 d26d3d2 e4babea 7f6c144 b4aa4ca 6a70131 9aa077c 411738c 8e0fb69 6d98e85 6d9e150 4899479 634def1 1f18452 2f92b22 23f232c dd3b8cd 1a7c360 87ecb64 0bde329 2d85a82 438e6b5 a9456fd ac05365 36ed547 4652ca7 a047a1b a4a30d7 1441ae6 8003808 5f43753 1c13d0f bae6b3d f422cf0 0229d74 aa40cf4 29085e1 00ffddf e81fa9c 0c8925f 96204a1 82930f7 8d24582 1fc7744 6cd428c 21693e0 b65ffad 1f438e3 f3928fb 089f8ab 700650a 452c229 e3e0e57 78751c2 203d561 eb1c67d e08aa79 c1ee04b 827e563 ca4a7fd ed185c0 b3407ac a4011eb fc1ca3c 1b1841f b3b315a 3ab4176 8102475 8c329eb 78d4960 4e3d914 5e4aaa7 7f77563 f88d6f7 7aa78ba 2d737f8 833899a 236b49c 8230347 bf33a57 738acfe 032ec02 77e389a 61031d7 a094b3d ace4856 fc6a1c7 900afcf 0baa3e9 f95106e e57e24a ce1c970 a7e1216 2548d6a 02e3863 1997cff af2d1de 64f5778 4151510 ac9bd41 5462bd7 c1c6428 7ab2736 bd6f966 8068daf 5691506 575d61a 4065bdb File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -162,6 +162,7 @@ class PeriodIndex(DatelikeOps, DatetimeIndexOpsMixin, | |
| _infer_as_myclass = True | ||
| | ||
| _freq = None | ||
| _data = None # type: PeriodArray | ||
| | ||
| _engine_type = libindex.PeriodEngine | ||
| | ||
| | @@ -177,47 +178,18 @@ def __new__(cls, data=None, ordinal=None, freq=None, start=None, end=None, | |
| tz=tz, dtype=dtype, copy=copy, **fields) | ||
| return cls._simple_new(data, name=name) | ||
| | ||
| # ------------------------------------------------------------------------ | ||
| # Data | ||
| @property | ||
| def _ndarray_values(self): | ||
| return self.values.values | ||
| | ||
| # ------------------------------------------------------------------------ | ||
| # Mixin Candidates | ||
| # err. maybe not... | ||
| | ||
| @property | ||
| def _box_func(self): | ||
| def func(x): | ||
| if isinstance(x, Period) or x is tslib.NaT: | ||
| return x | ||
| else: | ||
| return Period._from_ordinal(ordinal=x, freq=self.freq) | ||
| return func | ||
| | ||
| # ------------------------------------------------------------------------ | ||
| # Straight Dispatch | ||
| | ||
| @property | ||
| def freq(self): | ||
| """Return the frequency object if it is set, otherwise None""" | ||
| return self.values.freq | ||
| def values(self): | ||
| return self._data | ||
| | ||
| # ------------------------------------------------------------------------ | ||
| # Dispatch and Wrap | ||
| | ||
| def asfreq(self, freq=None, how='E'): | ||
| result = self.values.asfreq(freq=freq, how=how) | ||
| return self._simple_new(result, name=self.name) | ||
| # ------------------------------------------------------------------------ | ||
| | ||
| | ||
| @cache_readonly | ||
| def _engine(self): | ||
| return self._engine_type(lambda: self._ndarray_values, len(self)) | ||
| | ||
| @property | ||
| def asi8(self): | ||
| return self.values.asi8 | ||
| # Index Constructors | ||
| | ||
| @classmethod | ||
| def _simple_new(cls, values, name=None, freq=None, **kwargs): | ||
| | @@ -265,28 +237,67 @@ def _shallow_copy(self, values=None, **kwargs): | |
| attributes['dtype'] = self.dtype | ||
| return self._simple_new(values, **attributes) | ||
| | ||
| def _shallow_copy_with_infer(self, values=None, **kwargs): | ||
| """ we always want to return a PeriodIndex """ | ||
| return self._shallow_copy(values=values, **kwargs) | ||
| | ||
| # ------------------------------------------------------------------------ | ||
| # Boxing | ||
| # err. maybe not... | ||
| ||
| | ||
| @property | ||
| def _box_func(self): | ||
| def func(x): | ||
| if isinstance(x, Period) or x is tslib.NaT: | ||
| return x | ||
| else: | ||
| return Period._from_ordinal(ordinal=x, freq=self.freq) | ||
| return func | ||
| | ||
| def _maybe_box_as_values(self, values, **attribs): | ||
| Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this (and _maybe_box_as_index) used? Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's used in the Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The only place I'm seeing it is in Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was talking about this branch I think (I don't think it is used in master?) | ||
| """Box an array of ordinals to a PeriodArray | ||
| | ||
| This is purely for compatibility between PeriodIndex | ||
| and Datetime/TimedeltaIndex. Once these are all backed by | ||
| an ExtensionArray, this can be removed | ||
| """ | ||
| freq = attribs['freq'] | ||
| return PeriodArray._from_ordinals(values, freq=freq) | ||
| | ||
| def shift(self, n): | ||
| # TODO: May need to | ||
| result = self.values.shift(n) | ||
| return self._simple_new(result, name=self.name) | ||
| # ------------------------------------------------------------------------ | ||
| # Straight Dispatch | ||
| | ||
| def _shallow_copy_with_infer(self, values=None, **kwargs): | ||
| """ we always want to return a PeriodIndex """ | ||
| return self._shallow_copy(values=values, **kwargs) | ||
| @property | ||
| def freq(self): | ||
| """Return the frequency object if it is set, otherwise None""" | ||
| return self._data.freq | ||
| | ||
| def _coerce_scalar_to_index(self, item): | ||
| """ | ||
| we need to coerce a scalar to a compat for our index type | ||
| @property | ||
| def asi8(self): | ||
| return self._data.asi8 | ||
| | ||
| Parameters | ||
| ---------- | ||
| item : scalar item to coerce | ||
| """ | ||
| return PeriodIndex([item], **self._get_attributes_dict()) | ||
| @property | ||
| def size(self): | ||
| # Avoid materializing self._values | ||
| return self._data.size | ||
| | ||
| @property | ||
| def shape(self): | ||
| # Avoid materializing self._values | ||
| return self._data.shape | ||
| # ------------------------------------------------------------------------ | ||
| # Dispatch and Wrap | ||
| | ||
| def asfreq(self, freq=None, how='E'): | ||
| result = self._data.asfreq(freq=freq, how=how) | ||
| return self._simple_new(result, name=self.name) | ||
| | ||
| # ------------------------------------------------------------------------ | ||
| # Indexing | ||
| @cache_readonly | ||
| def _engine(self): | ||
| # TODO: understand indexing before just changing this. | ||
| return self._engine_type(lambda: self._ndarray_values, len(self)) | ||
| | ||
| @Appender(_index_shared_docs['__contains__']) | ||
| def __contains__(self, key): | ||
| | @@ -308,9 +319,41 @@ def __contains__(self, key): | |
| def _int64index(self): | ||
| return Int64Index(self.asi8, name=self.name, fastpath=True) | ||
| | ||
| @property | ||
| def values(self): | ||
| return self._data | ||
| # ------------------------------------------------------------------------ | ||
| # Index Methods | ||
| | ||
| def shift(self, n): | ||
| """ | ||
| Specialized shift which produces a PeriodIndex | ||
| | ||
| Parameters | ||
| ---------- | ||
| n : int | ||
| Periods to shift by | ||
| | ||
| Returns | ||
| ------- | ||
| shifted : PeriodIndex | ||
| """ | ||
| # TODO: docs | ||
| # Note, this differs from the definition of ExtensionArray.shift | ||
| # 1. EA.shift takes a single `periods` argument, this accepts array | ||
| # 2. This accepts a `freq` argument | ||
| # so we don't dispatch | ||
| values = self._ndarray_values + n * self.freq.n | ||
| if self.hasnans: | ||
| values[self._isnan] = tslib.iNaT | ||
| return self._shallow_copy(values=values) | ||
| | ||
| def _coerce_scalar_to_index(self, item): | ||
| """ | ||
| we need to coerce a scalar to a compat for our index type | ||
| | ||
| Parameters | ||
| ---------- | ||
| item : scalar item to coerce | ||
| """ | ||
| return PeriodIndex([item], **self._get_attributes_dict()) | ||
| Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any particular reason for PeriodIndex instead of type(self) or shallow_copy? | ||
| | ||
| def __array__(self, dtype=None): | ||
| if is_integer_dtype(dtype): | ||
| | @@ -362,16 +405,6 @@ def _to_embed(self, keep_tz=False, dtype=None): | |
| | ||
| return self.astype(object).values | ||
| | ||
| @property | ||
| def size(self): | ||
| # Avoid materializing self._values | ||
| return self._ndarray_values.size | ||
| | ||
| @property | ||
| def shape(self): | ||
| # Avoid materializing self._values | ||
| return self._ndarray_values.shape | ||
| | ||
| @property | ||
| def _formatter_func(self): | ||
| return lambda x: "'%s'" % x | ||
| | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.values._data?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or
self._data._datato avoid extra indirectionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or
self._data._ndarray_values?