From af631b0e372e7850709f39b972138f4259f3d9b0 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 29 Oct 2018 18:36:40 -0700 Subject: [PATCH 1/5] reference asi8 instead of _data --- pandas/core/arrays/period.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 31bcac2f4f529..4e3d23dcd73f7 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -262,7 +262,7 @@ def _concat_same_type(cls, to_concat): freq = {x.freq for x in to_concat} assert len(freq) == 1 freq = list(freq)[0] - values = np.concatenate([x._data for x in to_concat]) + values = np.concatenate([x.asi8 for x in to_concat]) return cls(values, freq=freq) # -------------------------------------------------------------------- @@ -270,7 +270,7 @@ def _concat_same_type(cls, to_concat): @property def nbytes(self): # TODO(DatetimeArray): remove - return self._data.nbytes + return self.asi8.nbytes @cache_readonly def dtype(self): @@ -279,7 +279,7 @@ def dtype(self): @property def _ndarray_values(self): # Ordinals - return self._data + return self.asi8 @property def asi8(self): @@ -372,7 +372,7 @@ def __setitem__( msg = ("'value' should be a 'Period', 'NaT', or array of those. " "Got '{}' instead.".format(type(value).__name__)) raise TypeError(msg) - self._data[key] = value + self.asi8[key] = value def take(self, indices, allow_fill=False, fill_value=None): if allow_fill: @@ -391,7 +391,7 @@ def take(self, indices, allow_fill=False, fill_value=None): msg = "'fill_value' should be a Period. Got '{}'." raise ValueError(msg.format(fill_value)) - new_values = algos.take(self._data, + new_values = algos.take(self.asi8, indices, allow_fill=allow_fill, fill_value=fill_value) @@ -399,7 +399,7 @@ def take(self, indices, allow_fill=False, fill_value=None): return type(self)(new_values, self.freq) def isna(self): - return self._data == iNaT + return self.asi8 == iNaT def fillna(self, value=None, method=None, limit=None): # TODO(#20300) @@ -425,7 +425,7 @@ def fillna(self, value=None, method=None, limit=None): if mask.any(): if method is not None: func = pad_1d if method == 'pad' else backfill_1d - new_values = func(self._data, limit=limit, + new_values = func(self.asi8, limit=limit, mask=mask) new_values = type(self)(new_values, freq=self.freq) else: @@ -437,15 +437,15 @@ def fillna(self, value=None, method=None, limit=None): return new_values def copy(self, deep=False): - return type(self)(self._data.copy(), freq=self.freq) + return type(self)(self.asi8.copy(), freq=self.freq) def value_counts(self, dropna=False): from pandas import Series, PeriodIndex if dropna: - values = self[~self.isna()]._data + values = self[~self.isna()].asi8 else: - values = self._data + values = self.asi8 cls = type(self) @@ -638,7 +638,7 @@ def repeat(self, repeats, *args, **kwargs): """ # TODO(DatetimeArray): remove nv.validate_repeat(args, kwargs) - values = self._data.repeat(repeats) + values = self.asi8.repeat(repeats) return type(self)(values, self.freq) # Delegation... @@ -660,7 +660,7 @@ def astype(self, dtype, copy=True): elif is_string_dtype(dtype) and not is_categorical_dtype(dtype): return self._format_native_types() elif is_integer_dtype(dtype): - values = self._data + values = self.asi8 if values.dtype != dtype: # int32 vs. int64 @@ -689,7 +689,7 @@ def flags(self): # We need this since reduction.SeriesBinGrouper uses values.flags # Ideally, we wouldn't be passing objects down there in the first # place. - return self._data.flags + return self.asi8.flags # ------------------------------------------------------------------ # Arithmetic Methods From d31e9395304d143dfe14ae7b40c6bce1458cff3e Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 29 Oct 2018 18:37:50 -0700 Subject: [PATCH 2/5] remove no-longer-used wrapper --- pandas/core/indexes/period.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index c3728d8d956de..af36db2188357 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -48,17 +48,6 @@ dict(target_klass='PeriodIndex or list of Periods')) -def _wrap_field_accessor(name): - fget = getattr(PeriodArray, name).fget - - def f(self): - result = fget(self) - return Index(result, name=self.name) - - f.__name__ = name - f.__doc__ = fget.__doc__ - return property(f) - # --- Period index sketch From 73cec9b683a7607443cd46a387d804498a31d0a5 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 29 Oct 2018 18:48:55 -0700 Subject: [PATCH 3/5] use validation methods to simplify __new__ --- pandas/core/indexes/period.py | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index af36db2188357..e9dc6143a8775 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -30,6 +30,7 @@ from pandas.core.algorithms import unique1d from pandas.core.dtypes.dtypes import PeriodDtype +import pandas.core.arrays.datetimelike as dtl from pandas.core.arrays.period import PeriodArray, period_array from pandas.core.base import _shared_docs from pandas.core.indexes.base import _index_shared_docs, ensure_index @@ -200,27 +201,11 @@ def __new__(cls, data=None, ordinal=None, freq=None, start=None, end=None, if data is None and ordinal is None: # range-based. - if periods is not None: - if is_float(periods): - periods = int(periods) - - elif not is_integer(periods): - msg = 'periods must be a number, got {periods}' - raise TypeError(msg.format(periods=periods)) - data, freq = PeriodArray._generate_range(start, end, periods, freq, fields) data = PeriodArray(data, freq=freq) else: - if freq is None and dtype is not None: - freq = PeriodDtype(dtype).freq - elif freq and dtype: - freq = PeriodDtype(freq).freq - dtype = PeriodDtype(dtype).freq - - if freq != dtype: - msg = "specified freq and dtype are different" - raise IncompatibleFrequency(msg) + freq = dtl.validate_dtype_freq(dtype, freq) # PeriodIndex allow PeriodIndex(period_index, freq=different) # Let's not encourage that kind of behavior in PeriodArray. From f5b4da0b2d5f9b189aa2d2ff9d3c89e1a9cfd891 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 29 Oct 2018 20:00:57 -0700 Subject: [PATCH 4/5] add freq validation --- pandas/core/arrays/datetimelike.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 0247ce8dc6ac4..dc7cf51ca109d 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -944,6 +944,9 @@ def validate_dtype_freq(dtype, freq): ValueError : non-period dtype IncompatibleFrequency : mismatch between dtype and freq """ + if freq is not None: + freq = frequencies.to_offset(freq) + if dtype is not None: dtype = pandas_dtype(dtype) if not is_period_dtype(dtype): From 33e38fa234dca962e6ad5774035fea466aed7c78 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Mon, 29 Oct 2018 21:13:05 -0700 Subject: [PATCH 5/5] Fixup remove unused import --- pandas/core/indexes/period.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index e9dc6143a8775..ae5c3ddc9dfb4 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -29,7 +29,6 @@ from pandas._libs.tslibs import resolution from pandas.core.algorithms import unique1d -from pandas.core.dtypes.dtypes import PeriodDtype import pandas.core.arrays.datetimelike as dtl from pandas.core.arrays.period import PeriodArray, period_array from pandas.core.base import _shared_docs