Skip to content

Make Period - Period return DateOffset instead of int #21314

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 12 commits into from
Jun 29, 2018

Conversation

jbrockmendel
Copy link
Member

@jbrockmendel jbrockmendel commented Jun 4, 2018

Discussed briefly in #20049.

  • closes #xxxx
  • tests added / passed
  • passes git diff upstream/master -u -- "*.py" | flake8 --diff
  • whatsnew entry

@@ -557,7 +557,7 @@ def is_full(self):
return True
if not self.is_monotonic:
raise ValueError('Index is not monotonic')
values = self.values
values = self.asi8
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the docstring for is_full correct? It looks to me like 1) it is flipped True/False and 2) the word "missing" is ambiguous since it can refer to pd.NaT/np.nan

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to update, I don't remember why this was added / what is purpose is

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I don't remember even why we have this (can follow up later)

if self.freq != other.freq:
msg = _DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr)
raise IncompatibleFrequency(msg)

asi8 = self.asi8
new_data = asi8 - other.ordinal
new_data = np.array([self.freq * x for x in new_data])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to implement DateOffset * arraylike so we don't have to right this broadcasting repeatedly.

# GH#??? PeriodIndex - Period returns an object-index
# of DateOffset objects, for which we cannot use __neg__
# directly, so we have to apply it pointwise
return other.__sub__(self).map(lambda x: -x)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense for the object-dtype Index to attempt __neg__ like this?

@codecov
Copy link

codecov bot commented Jun 4, 2018

Codecov Report

Merging #21314 into master will decrease coverage by <.01%.
The diff coverage is 71.42%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #21314      +/-   ##
==========================================
- Coverage    91.9%   91.89%   -0.01%     
==========================================
  Files         154      154              
  Lines       49558    49562       +4     
==========================================
+ Hits        45545    45547       +2     
- Misses       4013     4015       +2
Flag Coverage Δ
#multiple 90.27% <71.42%> (-0.01%) ⬇️
#single 42.02% <0%> (-0.01%) ⬇️
Impacted Files Coverage Δ
pandas/core/indexes/period.py 92.67% <100%> (ø) ⬆️
pandas/core/indexes/datetimelike.py 96.55% <50%> (-0.34%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 45e55af...efd7c75. Read the comment docs.

@jschendel jschendel added Frequency DateOffsets Period Period data type labels Jun 4, 2018
@@ -557,7 +557,7 @@ def is_full(self):
return True
if not self.is_monotonic:
raise ValueError('Index is not monotonic')
values = self.values
values = self.asi8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to update, I don't remember why this was added / what is purpose is

@@ -899,7 +899,9 @@ def __add__(self, other):
raise TypeError("cannot add {dtype}-dtype to {cls}"
.format(dtype=other.dtype,
cls=type(self).__name__))

elif is_categorical_dtype(other):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can make this is_extension_dtype (here and below)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should work for now, but it isn't obvious to me how it will shake out as more EA subclasses get implemented. Let me give this some thought.

return -other.__sub__(self)
# GH#21314 PeriodIndex - Period returns an object-index
# of DateOffset objects, for which we cannot use __neg__
# directly, so we have to apply it pointwise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a test that hits this explicity?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Without this we get test failures in tests.indexes.period.test_arithmetic.TestPeriodIndexSeriesMethods for
test_pi_ops, test_pi_sub_period, test_pi_sub_period_nat

@@ -29,6 +29,8 @@ Datetimelike API Changes
^^^^^^^^^^^^^^^^^^^^^^^^

- For :class:`DatetimeIndex` and :class:`TimedeltaIndex` with non-``None`` ``freq`` attribute, addition or subtraction of integer-dtyped array or ``Index`` will return an object of the same class (:issue:`19959`)
- Subtraction of :class:`Period` from :class:`Period` will return a :class:`DateOffset` object instead of an integer (:issue:`21314`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make a new sub-section and show a previous / new behavior example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "can" part of that is a very good question. I'll try.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your subsection looks good, you don't need this note here any longer

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. some minor comments. pls rebase. ping on green.

@@ -26,10 +26,52 @@ Backwards incompatible API changes

.. _whatsnew_0240.api.datetimelike:

Period Subtraction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a reference tag here

In [4]: june - april
Out [4]: 2

Similarly, subtraction of a ``Period`` from a ``PeriodIndex`` will not return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will now return

@@ -29,6 +29,8 @@ Datetimelike API Changes
^^^^^^^^^^^^^^^^^^^^^^^^

- For :class:`DatetimeIndex` and :class:`TimedeltaIndex` with non-``None`` ``freq`` attribute, addition or subtraction of integer-dtyped array or ``Index`` will return an object of the same class (:issue:`19959`)
- Subtraction of :class:`Period` from :class:`Period` will return a :class:`DateOffset` object instead of an integer (:issue:`21314`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your subsection looks good, you don't need this note here any longer

@@ -557,7 +557,7 @@ def is_full(self):
return True
if not self.is_monotonic:
raise ValueError('Index is not monotonic')
values = self.values
values = self.asi8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I don't remember even why we have this (can follow up later)

@jreback jreback added this to the 0.24.0 milestone Jun 19, 2018
@jbrockmendel
Copy link
Member Author

gentle ping

@jreback
Copy link
Contributor

jreback commented Jun 26, 2018

i rebased. ping on green. (note periodically you can rebase long running PR's)

@jbrockmendel
Copy link
Member Author

Ping

@jreback jreback merged commit 5afb953 into pandas-dev:master Jun 29, 2018
@jreback
Copy link
Contributor

jreback commented Jun 29, 2018

thanks!

Sup3rGeo pushed a commit to Sup3rGeo/pandas that referenced this pull request Oct 1, 2018
@jbrockmendel jbrockmendel deleted the persub branch April 5, 2020 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Frequency DateOffsets Period Period data type
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants