Skip to content

Implement small, easy bits of other PRs #23173

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
wants to merge 11 commits into from
11 changes: 6 additions & 5 deletions pandas/core/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def _add_delegate_accessors(cls, delegate, accessors, typ,
overwrite : boolean, default False
overwrite the method/property in the target class if it exists
"""

def _create_delegator_property(name):

def _getter(self):
Expand Down Expand Up @@ -107,9 +106,10 @@ def f(self, *args, **kwargs):

def delegate_names(delegate, accessors, typ, overwrite=False):
"""
Add delegated names to a class using a class decorator. This provides
an alternative usage to directly calling `_add_delegate_accessors`
below a class definition.
Add delegated names to a class using a class decorator.

This provides an alternative usage to directly calling
`_add_delegate_accessors` below a class definition.

Parameters
----------
Expand All @@ -121,7 +121,8 @@ def delegate_names(delegate, accessors, typ, overwrite=False):

Returns
-------
decorator
callable
A class decorator

Examples
--------
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def _from_factorized(cls, values, original):
Parameters
----------
values : ndarray
An integer ndarray with the factorized values.
An ndarray with the unique factorized values.
original : ExtensionArray
The original ExtensionArray that factorize was called on.

Expand Down
27 changes: 17 additions & 10 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
from pandas._libs.tslibs.period import (
Period, DIFFERENT_FREQ_INDEX, IncompatibleFrequency)

from pandas.errors import NullFrequencyError, PerformanceWarning
from pandas.errors import (
NullFrequencyError, PerformanceWarning, AbstractMethodError)
from pandas import compat

from pandas.tseries import frequencies
Expand Down Expand Up @@ -77,12 +78,10 @@ class AttributesMixin(object):
@property
def _attributes(self):
# Inheriting subclass should implement _attributes as a list of strings
from pandas.errors import AbstractMethodError
raise AbstractMethodError(self)

@classmethod
def _simple_new(cls, values, **kwargs):
from pandas.errors import AbstractMethodError
raise AbstractMethodError(cls)

def _get_attributes_dict(self):
Expand Down Expand Up @@ -119,7 +118,7 @@ def _box_func(self):
"""
box function to get object from internal representation
"""
raise com.AbstractMethodError(self)
raise AbstractMethodError(self)

def _box_values(self, values):
"""
Expand Down Expand Up @@ -332,6 +331,11 @@ def _validate_frequency(cls, index, freq, **kwargs):
# Frequency validation is not meaningful for Period Array/Index
return None

# DatetimeArray may pass `ambiguous`, nothing else will be accepted
# by cls._generate_range below
acceptable = {'ambiguous'} if index.dtype.kind == 'M' else {}
assert all(key in acceptable for key in kwargs)

inferred = index.inferred_freq
if index.size == 0 or inferred == freq.freqstr:
return None
Expand All @@ -352,13 +356,13 @@ def _add_datelike(self, other):
typ=type(other).__name__))

def _sub_datelike(self, other):
raise com.AbstractMethodError(self)
raise AbstractMethodError(self)

def _sub_period(self, other):
return NotImplemented

def _add_offset(self, offset):
raise com.AbstractMethodError(self)
raise AbstractMethodError(self)

def _add_delta(self, other):
return NotImplemented
Expand All @@ -380,7 +384,7 @@ def _add_delta_tdi(self, other):
Add a delta of a TimedeltaIndex
return the i8 result view
"""
if not len(self) == len(other):
if len(self) != len(other):
raise ValueError("cannot add indices of unequal length")

if isinstance(other, np.ndarray):
Expand Down Expand Up @@ -441,7 +445,7 @@ def _sub_period_array(self, other):
.format(dtype=other.dtype,
cls=type(self).__name__))

if not len(self) == len(other):
if len(self) != len(other):
raise ValueError("cannot subtract arrays/indices of "
"unequal length")
if self.freq != other.freq:
Expand Down Expand Up @@ -595,9 +599,12 @@ def _time_shift(self, periods, freq=None):

start = self[0] + periods * self.freq
end = self[-1] + periods * self.freq
attribs = self._get_attributes_dict()

# Note: in the DatetimeTZ case, _generate_range will infer the
# appropriate timezone from `start` and `end`, so tz does not need
# to be passed explicitly.
return self._generate_range(start=start, end=end, periods=None,
**attribs)
freq=self.freq)

@classmethod
def _add_datetimelike_methods(cls):
Expand Down
48 changes: 3 additions & 45 deletions pandas/core/arrays/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import numpy as np

from pandas._libs import lib
from pandas._libs.tslib import NaT, iNaT
from pandas._libs.tslibs.period import (
Period, IncompatibleFrequency, DIFFERENT_FREQ_INDEX,
Expand All @@ -26,7 +25,7 @@
import pandas.core.common as com

from pandas.tseries import frequencies
from pandas.tseries.offsets import Tick, DateOffset
from pandas.tseries.offsets import Tick

from pandas.core.arrays import datetimelike as dtl
from pandas.core.arrays.datetimelike import DatetimeLikeArrayMixin
Expand Down Expand Up @@ -176,11 +175,12 @@ def _from_ordinals(cls, values, freq=None, **kwargs):

@classmethod
def _generate_range(cls, start, end, periods, freq, fields):
periods = dtl.validate_periods(periods)
if freq is not None:
freq = Period._maybe_convert_freq(freq)

field_count = len(fields)
if com.count_not_none(start, end) > 0:
if start is not None or end is not None:
if field_count > 0:
raise ValueError('Can either instantiate from fields '
'or endpoints, but not both')
Expand Down Expand Up @@ -445,48 +445,6 @@ def _time_shift(self, n):
values[self._isnan] = iNaT
return self._shallow_copy(values=values)

def _maybe_convert_timedelta(self, other):
"""
Convert timedelta-like input to an integer multiple of self.freq

Parameters
----------
other : timedelta, np.timedelta64, DateOffset, int, np.ndarray

Returns
-------
converted : int, np.ndarray[int64]

Raises
------
IncompatibleFrequency : if the input cannot be written as a multiple
of self.freq. Note IncompatibleFrequency subclasses ValueError.
"""
if isinstance(
other, (timedelta, np.timedelta64, Tick, np.ndarray)):
offset = frequencies.to_offset(self.freq.rule_code)
if isinstance(offset, Tick):
# _check_timedeltalike_freq_compat will raise if incompatible
delta = self._check_timedeltalike_freq_compat(other)
return delta
elif isinstance(other, DateOffset):
freqstr = other.rule_code
base = frequencies.get_base_alias(freqstr)
if base == self.freq.rule_code:
return other.n
msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr)
raise IncompatibleFrequency(msg)
elif lib.is_integer(other):
# integer is passed to .shift via
# _add_datetimelike_methods basically
# but ufunc may pass integer to _add_delta
return other

# raise when input doesn't have freq
msg = "Input has different freq from {cls}(freq={freqstr})"
raise IncompatibleFrequency(msg.format(cls=type(self).__name__,
freqstr=self.freqstr))

def _check_timedeltalike_freq_compat(self, other):
"""
Arithmetic operations with timedelta-like scalars or array `other`
Expand Down
6 changes: 2 additions & 4 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ def __new__(cls, values, freq=None, start=None, end=None, periods=None,
return result

@classmethod
def _generate_range(cls, start, end, periods, freq, closed=None, **kwargs):
# **kwargs are for compat with TimedeltaIndex, which includes `name`
def _generate_range(cls, start, end, periods, freq, closed=None):

periods = dtl.validate_periods(periods)
if freq is None and any(x is None for x in [periods, start, end]):
Expand All @@ -167,10 +166,9 @@ def _generate_range(cls, start, end, periods, freq, closed=None, **kwargs):

if freq is not None:
index = _generate_regular_range(start, end, periods, freq)
index = cls._simple_new(index, freq=freq, **kwargs)
index = cls._simple_new(index, freq=freq)
else:
index = np.linspace(start.value, end.value, periods).astype('i8')
# TODO: shouldn't we pass `name` here? (via **kwargs)
index = cls._simple_new(index, freq=freq)

if not left_closed:
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -4942,7 +4942,7 @@ def _combine_match_index(self, other, func, level=None):
index=left.index, columns=self.columns,
copy=False)

def _combine_match_columns(self, other, func, level=None, try_cast=True):
def _combine_match_columns(self, other, func, level=None):
assert isinstance(other, Series)
left, right = self.align(other, join='outer', axis=1, level=level,
copy=False)
Expand Down
3 changes: 1 addition & 2 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class Index(IndexOpsMixin, PandasObject):
_outer_indexer = libjoin.outer_join_indexer_object

_typ = 'index'
_data = None
_data = None # type: Union[np.ndarray, ExtensionArray]
_id = None
name = None
asi8 = None
Expand Down Expand Up @@ -261,7 +261,6 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None,
return cls._simple_new(data, name)

from .range import RangeIndex

# range
if isinstance(data, RangeIndex):
return RangeIndex(start=data, copy=copy, dtype=dtype, name=name)
Expand Down
6 changes: 6 additions & 0 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,12 @@ def astype(self, dtype, copy=True):
raise TypeError(msg.format(name=type(self).__name__, dtype=dtype))
return super(DatetimeIndexOpsMixin, self).astype(dtype, copy=copy)

@Appender(DatetimeLikeArrayMixin._time_shift.__doc__)
def _time_shift(self, periods, freq=None):
result = DatetimeLikeArrayMixin._time_shift(self, periods, freq=freq)
result.name = self.name
return result


def _ensure_datetimelike_to_i8(other, to_utc=False):
"""
Expand Down
19 changes: 5 additions & 14 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,11 @@ def __new__(cls, data=None,

if data is None:
# TODO: Remove this block and associated kwargs; GH#20535
return cls._generate_range(start, end, periods, name, freq,
tz=tz, normalize=normalize,
closed=closed, ambiguous=ambiguous)
result = cls._generate_range(start, end, periods,
freq=freq, tz=tz, normalize=normalize,
closed=closed, ambiguous=ambiguous)
result.name = name
return result

if not isinstance(data, (np.ndarray, Index, ABCSeries,
DatetimeArrayMixin)):
Expand Down Expand Up @@ -315,17 +317,6 @@ def __new__(cls, data=None,

return subarr._deepcopy_if_needed(ref_to_data, copy)

@classmethod
@Appender(DatetimeArrayMixin._generate_range.__doc__)
def _generate_range(cls, start, end, periods, name=None, freq=None,
tz=None, normalize=False, ambiguous='raise',
closed=None):
out = super(DatetimeIndex, cls)._generate_range(
start, end, periods, freq,
tz=tz, normalize=normalize, ambiguous=ambiguous, closed=closed)
out.name = name
return out

def _convert_for_op(self, value):
""" Convert value to be insertable to ndarray """
if self._has_same_tz(value):
Expand Down
Loading