-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
CLN: Make ufunc works for Index #10638
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,8 @@ | |
import pandas.core.common as com | ||
from pandas.core.common import (isnull, _INT64_DTYPE, _maybe_box, | ||
_values_from_object, ABCSeries, | ||
is_integer, is_float, is_object_dtype) | ||
is_integer, is_float, is_object_dtype, | ||
is_float_dtype) | ||
from pandas import compat | ||
from pandas.util.decorators import cache_readonly | ||
|
||
|
@@ -307,6 +308,30 @@ def __contains__(self, key): | |
return False | ||
return key.ordinal in self._engine | ||
|
||
def __array_wrap__(self, result, context=None): | ||
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. doesn't this need to go in 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.
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. I agree that tests for these other index types would be a good idea, though. Also, I think we should probably prohibit all ufuncs on PeriodIndex, not just those that return float. For example, it's not valid to square periods, even though that returns integers. 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. Raising
So it can't be prohibited? 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. PeriodIndex + integer ndarray should not be expected to work -- the array On Mon, Aug 17, 2015 at 3:35 PM, Sinhrks [email protected] wrote:
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. actually I disagree 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. Yes, because this is a valid freq shift,
And #10744 has been done expecting arithmetic using 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. Reconsidered this, and defining
NOTE: Maybe not intentional, 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. @sinhrks remember that ATM So its needs handling to error on prohibited ops. So on on raising in |
||
""" | ||
Gets called after a ufunc. Needs additional handling as | ||
PeriodIndex stores internal data as int dtype | ||
|
||
Replace this to __numpy_ufunc__ in future version | ||
""" | ||
if isinstance(context, tuple) and len(context) > 0: | ||
func = context[0] | ||
if (func is np.add): | ||
return self._add_delta(context[1][1]) | ||
elif (func is np.subtract): | ||
return self._add_delta(-context[1][1]) | ||
elif isinstance(func, np.ufunc): | ||
if 'M->M' not in func.types: | ||
msg = "ufunc '{0}' not supported for the PeriodIndex" | ||
# This should be TypeError, but TypeError cannot be raised | ||
# from here because numpy catches. | ||
raise ValueError(msg.format(func.__name__)) | ||
|
||
if com.is_bool_dtype(result): | ||
return result | ||
return PeriodIndex(result, freq=self.freq, name=self.name) | ||
|
||
@property | ||
def _box_func(self): | ||
return lambda x: Period._from_ordinal(ordinal=x, freq=self.freq) | ||
|
@@ -522,7 +547,18 @@ def _maybe_convert_timedelta(self, other): | |
base = frequencies.get_base_alias(freqstr) | ||
if base == self.freq.rule_code: | ||
return other.n | ||
raise ValueError("Input has different freq from PeriodIndex(freq={0})".format(self.freq)) | ||
elif isinstance(other, np.ndarray): | ||
if com.is_integer_dtype(other): | ||
return other | ||
elif com.is_timedelta64_dtype(other): | ||
offset = frequencies.to_offset(self.freq) | ||
if isinstance(offset, offsets.Tick): | ||
nanos = tslib._delta_to_nanoseconds(other) | ||
offset_nanos = tslib._delta_to_nanoseconds(offset) | ||
if (nanos % offset_nanos).all() == 0: | ||
return nanos // offset_nanos | ||
msg = "Input has different freq from PeriodIndex(freq={0})" | ||
raise ValueError(msg.format(self.freqstr)) | ||
|
||
def _add_delta(self, other): | ||
ordinal_delta = self._maybe_convert_timedelta(other) | ||
|
@@ -775,14 +811,6 @@ def _format_native_types(self, na_rep=u('NaT'), date_format=None, **kwargs): | |
values[imask] = np.array([formatter(dt) for dt in values[imask]]) | ||
return values | ||
|
||
def __array_finalize__(self, obj): | ||
if not self.ndim: # pragma: no cover | ||
return self.item() | ||
|
||
self.freq = getattr(obj, 'freq', None) | ||
self.name = getattr(obj, 'name', None) | ||
self._reset_identity() | ||
|
||
def take(self, indices, axis=0): | ||
""" | ||
Analogous to ndarray.take | ||
|
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.
why the different exception behavior?
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.
TypeError
raised from__array_wrap__
seems to be catchrd bynumpy
and return unintended result.