Skip to content

REF: simplify PeriodIndex._shallow_copy #32280

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

Merged
merged 19 commits into from
Mar 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
899cb05
stricten, tests
jbrockmendel Jan 29, 2020
76ea1fb
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Jan 29, 2020
b536140
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 1, 2020
5647780
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 3, 2020
1c9b523
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 4, 2020
3b2bcae
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 21, 2020
94cc942
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 22, 2020
795cb9a
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 22, 2020
01be68c
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 22, 2020
7fb95a3
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 23, 2020
f1b88d3
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 24, 2020
80cee08
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 25, 2020
0c227f2
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 26, 2020
3548875
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 26, 2020
d19ebf7
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 26, 2020
b4131eb
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 26, 2020
42de183
Test for where
jbrockmendel Feb 26, 2020
9c9b927
Merge branch 'master' of https://github.com/pandas-dev/pandas into sh…
jbrockmendel Feb 26, 2020
9cb67b4
semi-simplify
jbrockmendel Feb 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4234,6 +4234,9 @@ def putmask(self, mask, value):
values = self.values.copy()
try:
np.putmask(values, mask, self._convert_for_op(value))
if is_period_dtype(self.dtype):
# .values cast to object, so we need to cast back
values = type(self)(values)._data
return self._shallow_copy(values)
except (ValueError, TypeError) as err:
if is_object_dtype(self):
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,8 @@ def where(self, cond, other=None):
other = other.view("i8")

result = np.where(cond, values, other).astype("i8")
return self._shallow_copy(result)
arr = type(self._data)._simple_new(result, dtype=self.dtype)
return type(self)._simple_new(arr, name=self.name)

def _summary(self, name=None) -> str:
"""
Expand Down
16 changes: 3 additions & 13 deletions pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,22 +250,11 @@ def _has_complex_internals(self):
return True

def _shallow_copy(self, values=None, name: Label = no_default):
# TODO: simplify, figure out type of values
name = name if name is not no_default else self.name

if values is None:
values = self._data

if isinstance(values, type(self)):
values = values._data

if not isinstance(values, PeriodArray):
if isinstance(values, np.ndarray) and values.dtype == "i8":
values = PeriodArray(values, freq=self.freq)
else:
# GH#30713 this should never be reached
raise TypeError(type(values), getattr(values, "dtype", None))

return self._simple_new(values, name=name)

def _maybe_convert_timedelta(self, other):
Expand Down Expand Up @@ -618,10 +607,11 @@ def insert(self, loc, item):
if not isinstance(item, Period) or self.freq != item.freq:
return self.astype(object).insert(loc, item)

idx = np.concatenate(
i8result = np.concatenate(
(self[:loc].asi8, np.array([item.ordinal]), self[loc:].asi8)
)
return self._shallow_copy(idx)
arr = type(self._data)._simple_new(i8result, dtype=self.dtype)
return type(self)._simple_new(arr, name=self.name)

def join(self, other, how="left", level=None, return_indexers=False, sort=False):
"""
Expand Down
5 changes: 5 additions & 0 deletions pandas/tests/base/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
is_datetime64_dtype,
is_datetime64tz_dtype,
is_object_dtype,
is_period_dtype,
needs_i8_conversion,
)

Expand Down Expand Up @@ -295,6 +296,10 @@ def test_value_counts_unique_nunique_null(self, null_obj, index_or_series_obj):
obj[0:2] = pd.NaT
values = obj._values

elif is_period_dtype(obj):
values[0:2] = iNaT
parr = type(obj._data)(values, dtype=obj.dtype)
values = obj._shallow_copy(parr)
elif needs_i8_conversion(obj):
values[0:2] = iNaT
values = obj._shallow_copy(values)
Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/indexes/datetimes/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ def test_dti_custom_getitem_matplotlib_hackaround(self):


class TestWhere:
def test_where_doesnt_retain_freq(self):
dti = date_range("20130101", periods=3, freq="D", name="idx")
cond = [True, True, False]
expected = DatetimeIndex([dti[0], dti[1], dti[0]], freq=None, name="idx")

result = dti.where(cond, dti[::-1])
tm.assert_index_equal(result, expected)

def test_where_other(self):
# other is ndarray or Index
i = pd.date_range("20130101", periods=3, tz="US/Eastern")
Expand Down
12 changes: 8 additions & 4 deletions pandas/tests/indexes/period/test_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,19 +117,23 @@ def test_make_time_series(self):
assert isinstance(series, Series)

def test_shallow_copy_empty(self):

# GH13067
idx = PeriodIndex([], freq="M")
result = idx._shallow_copy()
expected = idx

tm.assert_index_equal(result, expected)

def test_shallow_copy_i8(self):
def test_shallow_copy_disallow_i8(self):
# GH-24391
pi = period_range("2018-01-01", periods=3, freq="2D")
result = pi._shallow_copy(pi.asi8)
tm.assert_index_equal(result, pi)
with pytest.raises(AssertionError, match="ndarray"):
pi._shallow_copy(pi.asi8)

def test_shallow_copy_requires_disallow_period_index(self):
pi = period_range("2018-01-01", periods=3, freq="2D")
with pytest.raises(AssertionError, match="PeriodIndex"):
pi._shallow_copy(pi)

def test_view_asi8(self):
idx = PeriodIndex([], freq="M")
Expand Down
7 changes: 5 additions & 2 deletions pandas/tests/indexes/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from pandas._libs.tslibs import iNaT

from pandas.core.dtypes.common import needs_i8_conversion
from pandas.core.dtypes.common import is_period_dtype, needs_i8_conversion

import pandas as pd
from pandas import CategoricalIndex, MultiIndex, RangeIndex
Expand Down Expand Up @@ -219,7 +219,10 @@ def test_get_unique_index(self, indices):
if not indices._can_hold_na:
pytest.skip("Skip na-check if index cannot hold na")

if needs_i8_conversion(indices):
if is_period_dtype(indices):
vals = indices[[0] * 5]._data
vals[0] = pd.NaT
elif needs_i8_conversion(indices):
vals = indices.asi8[[0] * 5]
vals[0] = iNaT
else:
Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/indexes/timedeltas/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ def test_timestamp_invalid_key(self, key):


class TestWhere:
def test_where_doesnt_retain_freq(self):
tdi = timedelta_range("1 day", periods=3, freq="D", name="idx")
cond = [True, True, False]
expected = TimedeltaIndex([tdi[0], tdi[1], tdi[0]], freq=None, name="idx")

result = tdi.where(cond, tdi[::-1])
tm.assert_index_equal(result, expected)

def test_where_invalid_dtypes(self):
tdi = timedelta_range("1 day", periods=3, freq="D", name="idx")

Expand Down