Skip to content
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

BUG: Let IntervalIndex constructor override inferred closed #21584

Merged
merged 1 commit into from
Jun 27, 2018

Conversation

jschendel
Copy link
Member

Makes IntervalIndex constructor behavior consistent: the closed parameter, if specified, takes priority over the inferred closed.

Comments:

  • Modified the intervals_to_interval_bounds function to optionally raise if mixed values of closed are encountered instead of automatically raising.
    • Allow creating an IntervalIndex from mixed closed lists, e.g.[Interval(0, 1, closed='left'), Interval(2, 3, closed='right')], only if closed is specified during construction.
    • The above will still raise if closed is not passed to the constructor.
    • This appears to only be called in the constructor currently.
  • Added an Interval subsection to the Bug Fixes section of the 0.24.0 whatsnew, since I anticipate that there will be a non-negligible number of interval related fixes.

@jschendel jschendel added Bug API Design Interval Interval data type labels Jun 22, 2018
@jschendel jschendel added this to the 0.24.0 milestone Jun 22, 2018
@codecov
Copy link

codecov bot commented Jun 22, 2018

Codecov Report

Merging #21584 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #21584      +/-   ##
==========================================
+ Coverage    91.9%    91.9%   +<.01%     
==========================================
  Files         153      153              
  Lines       49549    49546       -3     
==========================================
- Hits        45537    45536       -1     
+ Misses       4012     4010       -2
Flag Coverage Δ
#multiple 90.3% <100%> (ø) ⬆️
#single 41.78% <0%> (ø) ⬆️
Impacted Files Coverage Δ
pandas/core/indexes/interval.py 93.13% <100%> (-0.04%) ⬇️
pandas/util/testing.py 85.27% <0%> (+0.2%) ⬆️

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 f1ffc5f...5fe0cb3. Read the comment docs.

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.

question

@@ -317,13 +317,7 @@ def test_generic_errors(self, constructor):
pass

def test_constructor_errors(self, constructor):
# mismatched closed inferred from intervals vs constructor.
Copy link
Contributor

Choose a reason for hiding this comment

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

hmm, I think this is an invalid interval as its closed on both sides?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, my logic here is that if there's a conflict, then the user had to explicitly pass the conflicting value to the constructor since the default for closed is None. Being done explicitly seems to indicate (at least a degree of) user intention, so seems reasonable to defer to the user passed value if there's a conflict, as opposed to forcing preprocessing onto the user.

Can certainly see an argument for raising in this case though, so can modify to make the behavior consistent in regards to raising if that's the preferred behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

so thinking of the scenario where you have a list of Intervals and you are then overriding to make it uniform, but this actually changes what this represents; the user doesn't even know this. maybe a warning would be in order? ISince the override is explicit the user 'knows what they are doing', but do they really?

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, not sure. I think it would be OK to override without warning or error, but not really sure.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not opposed to adding a warning; will do that within the next day. Shouldn't be much work and will be easy enough to remove if we decide we don't want it later.

Another use case for overriding is to change closed for an existing IntervalIndex. A little bit different than the list of intervals case, but I think we'd want the constructor to have consistent behavior for list of intervals input and IntervalIndex input.

On master the closed parameter is ignored for IntervalIndex input:

In [2]: index = pd.interval_range(0, 3, closed='both')

In [3]: pd.IntervalIndex(index, closed='neither')
Out[3]:
IntervalIndex([[0, 1], [1, 2], [2, 3]]
              closed='both',
              dtype='interval[int64]')

And the best workaround (to my knowledge) is to deconstruct and pass to one of the from_* methods, which seems unnecessarily tedious, e.g.

In [4]: pd.IntervalIndex.from_arrays(index.left, index.right, closed='neither')
Out[4]:
IntervalIndex([(0, 1), (1, 2), (2, 3)]
              closed='neither',
              dtype='interval[int64]')

In [5]: pd.IntervalIndex.from_tuples(index.to_tuples(), closed='neither')
Out[5]:
IntervalIndex([(0, 1), (1, 2), (2, 3)]
              closed='neither',
              dtype='interval[int64]')

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe think about adding a set_closed method (similar to how we have accessors for names/labels/levels and so on on Indexes), though in the construtor is fine as well.

ok so merge this as is and do followup? (either way ok)

Copy link
Member Author

Choose a reason for hiding this comment

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

ok so merge this as is and do followup?

Merging as is. To be clear, for the followup are you referring to adding warnings, or just the set_closed?

@jschendel jschendel merged commit a620e72 into pandas-dev:master Jun 27, 2018
@jschendel jschendel deleted the ii-constructor-closed branch September 24, 2018 17:22
Sup3rGeo pushed a commit to Sup3rGeo/pandas that referenced this pull request Oct 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow IntervalIndex constructor closed parameter to override inferred closed
3 participants