-
-
Notifications
You must be signed in to change notification settings - Fork 18.7k
BUG: TimedeltaIndex.intersection #22114
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
Closed
kirkhansen
wants to merge
6
commits into
pandas-dev:master
from
kirkhansen:fix-descending-timedeltaindex-intersect
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
22a94f4
BUG: TimedeltaIndex.intersection
kirkhansen 568cb5b
What's new entry
kirkhansen 7e0079f
Remove redeclared functions
kirkhansen a051c0b
Attempting to fix some stuff
kirkhansen 2f5513c
Previously failed tests paassing
kirkhansen 4aac7e8
Be less confusing about dealing with the frequency
kirkhansen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,9 @@ | |
|
||
import pandas.io.formats.printing as printing | ||
|
||
from pandas.tseries.offsets import index_offsets_equal | ||
import pandas.tseries.frequencies as frequencies | ||
|
||
_index_doc_kwargs = dict(ibase._index_doc_kwargs) | ||
|
||
|
||
|
@@ -572,6 +575,92 @@ def _time_shift(self, periods, freq=None): | |
result.name = self.name | ||
return result | ||
|
||
def _fast_intersection(self, other): | ||
""" | ||
Speedy intersection that works only if certain assumptions are met. | ||
See intersection for details. | ||
Parameters | ||
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. Could you give a bit more color to |
||
---------- | ||
other | ||
|
||
Returns | ||
------- | ||
|
||
""" | ||
# Coerce into the same order | ||
ascending = self.is_monotonic_increasing | ||
if ascending != other.is_monotonic_increasing: | ||
other = other.sort_values(ascending=ascending) | ||
# Lots of 'if ascending' calls here to setup mirrored function calls | ||
first_comparison = '__le__' if ascending else '__ge__' | ||
second_comparison = '__lt__' if ascending else '__gt__' | ||
if getattr(self[0], first_comparison)(other[0]): | ||
left, right = self, other | ||
else: | ||
left, right = other, self | ||
|
||
if ascending: | ||
start = right[0] | ||
end = min(left[-1], right[-1]) | ||
else: | ||
start = min(left[0], right[0]) | ||
end = right[-1] | ||
if getattr(end, second_comparison, start): | ||
return left.values[slice(*left.slice_locs(start, end))] | ||
return [] | ||
|
||
def intersection(self, other): | ||
""" | ||
Specialized intersection for DateTimeIndexOpsMixin objects. | ||
May be much faster than Index.intersection. | ||
|
||
Fast intersection will occur if | ||
1. Both are in a sorted order | ||
2. Both indexes have a `freq` , and it's the same `freq` | ||
3. Both are monotonic | ||
|
||
Parameters | ||
---------- | ||
other : Index or array-like | ||
|
||
Returns | ||
------- | ||
Index | ||
A shallow copied intersection between the two things passed in | ||
""" | ||
# Run a few checks, and perform a regular intersection | ||
# if the conditions aren't just right for fast intersection | ||
# Perform a regular Index.intersection | ||
self._assert_can_do_setop(other) | ||
|
||
if self.equals(other): | ||
return self._get_reconciled_name_object(other) | ||
|
||
lengths = len(self), len(other) | ||
if lengths[0] == 0: | ||
return self | ||
if lengths[1] == 0: | ||
return other | ||
|
||
if (not index_offsets_equal(self, other) or | ||
not other.freq.isAnchored() or # for period intersections with freq | ||
(not self._is_strictly_monotonic or | ||
not other._is_strictly_monotonic)): | ||
result = Index.intersection(self, other) | ||
if result.empty: | ||
result = result.astype(self.dtype) | ||
freq = self.freq or other.freq | ||
result = self._shallow_copy(result._values, name=result.name, | ||
freq=freq) | ||
if result.freq is None: | ||
result.freq = frequencies.to_offset(result.inferred_freq) | ||
return result | ||
|
||
# Conditions met! | ||
intersected_slice = self._fast_intersection(other) | ||
name = ops.get_op_result_name(self, other) | ||
return self._shallow_copy(intersected_slice, name=name) | ||
|
||
|
||
def wrap_arithmetic_op(self, other, result): | ||
if result is NotImplemented: | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
are we actually using this? (it seems you in-lined it below), I actually prefer that to making a new method
Uh oh!
There was an error while loading. Please reload this page.
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.
The names are similar, but I'm calling this function twice in the intersection function to help me deal with the boolean logic (already hard for me to follow, even with this addition). I can remove this, and put this inline if you really want it that way.