Skip to content

DOC/CLN for GH7213/GH7206 #7216

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 1 commit into from
May 23, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions doc/source/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ regularity will result in a ``DatetimeIndex`` (but frequency is lost):
Time/Date Components
~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are several time/date properties that one can access from ``Timestamp`` or a collection of timestamps like a ``DateTimeIndex``.
There are several time/date properties that one can access from ``Timestamp`` or a collection of timestamps like a ``DateTimeIndex``.

.. csv-table::
:header: "Property", "Description"
Expand Down Expand Up @@ -604,7 +604,7 @@ in the usual way.
# Skip new years
dt = datetime(2013, 12, 17)
dt + bmth_us

# Define date index with custom offset
from pandas import DatetimeIndex
DatetimeIndex(start='20100101',end='20120101',freq=bmth_us)
Expand Down Expand Up @@ -789,8 +789,8 @@ methods to return a list of holidays and only ``rules`` need to be defined
in a specific holiday calendar class. Further, ``start_date`` and ``end_date``
class attributes determine over what date range holidays are generated. These
should be overwritten on the ``AbstractHolidayCalendar`` class to have the range
apply to all calendar subclasses. ``USFederalHolidayCalendar`` is the
only calendar that exists and primarily serves as an example for developing
apply to all calendar subclasses. ``USFederalHolidayCalendar`` is the
only calendar that exists and primarily serves as an example for developing
other calendars.

For holidays that occur on fixed dates (e.g., US Memorial Day or July 4th) an
Expand Down Expand Up @@ -823,12 +823,12 @@ An example of how holidays and holiday calendars are defined:
cal = ExampleCalendar()
cal.holidays(datetime(2012, 1, 1), datetime(2012, 12, 31))

Using this calendar, creating an index or doing offset arithmetic skips weekends
Using this calendar, creating an index or doing offset arithmetic skips weekends
and holidays (i.e., Memorial Day/July 4th).

.. ipython:: python

DatetimeIndex(start='7/1/2012', end='7/10/2012',
DatetimeIndex(start='7/1/2012', end='7/10/2012',
freq=CDay(calendar=cal)).to_pydatetime()
offset = CustomBusinessDay(calendar=cal)
datetime(2012, 5, 25) + offset
Expand All @@ -840,11 +840,11 @@ Ranges are defined by the ``start_date`` and ``end_date`` class attributes
of ``AbstractHolidayCalendar``. The defaults are below.

.. ipython:: python

AbstractHolidayCalendar.start_date
AbstractHolidayCalendar.end_date

These dates can be overwritten by setting the attributes as
These dates can be overwritten by setting the attributes as
datetime/Timestamp/string.

.. ipython:: python
Expand Down Expand Up @@ -1120,7 +1120,7 @@ Passing string represents lower frequency than `PeriodIndex` returns partial sli
dfp
dfp['2013-01-01 10H']

As the same as `DatetimeIndex`, the endpoints will be included in the result. Below example slices data starting from 10:00 to 11:59.
As the same as `DatetimeIndex`, the endpoints will be included in the result. Below example slices data starting from 10:00 to 11:59.

.. ipython:: python

Expand Down
65 changes: 39 additions & 26 deletions pandas/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,16 +201,6 @@ def __unicode__(self):
return "%s(%s, dtype='%s')" % (type(self).__name__, prepr, self.dtype)


# facilitate the properties on the wrapped ops
def _field_accessor(name, docstring=None):
op_accessor = '_{0}'.format(name)
def f(self):
return self._ops_compat(name,op_accessor)

f.__name__ = name
f.__doc__ = docstring
return property(f)

class IndexOpsMixin(object):
""" common ops mixin to support a unified inteface / docs for Series / Index """

Expand All @@ -219,24 +209,9 @@ def _is_allowed_index_op(self, name):
raise TypeError("cannot perform an {name} operations on this type {typ}".format(
name=name,typ=type(self._get_access_object())))

def _is_allowed_datetime_index_op(self, name):
if not self._allow_datetime_index_ops:
raise TypeError("cannot perform an {name} operations on this type {typ}".format(
name=name,typ=type(self._get_access_object())))

def _is_allowed_period_index_op(self, name):
if not self._allow_period_index_ops:
raise TypeError("cannot perform an {name} operations on this type {typ}".format(
name=name,typ=type(self._get_access_object())))

def _ops_compat(self, name, op_accessor):
from pandas.tseries.index import DatetimeIndex
from pandas.tseries.period import PeriodIndex

obj = self._get_access_object()
if isinstance(obj, DatetimeIndex):
self._is_allowed_datetime_index_op(name)
elif isinstance(obj, PeriodIndex):
self._is_allowed_period_index_op(name)
try:
return self._wrap_access_object(getattr(obj,op_accessor))
except AttributeError:
Expand Down Expand Up @@ -336,6 +311,44 @@ def factorize(self, sort=False, na_sentinel=-1):
from pandas.core.algorithms import factorize
return factorize(self, sort=sort, na_sentinel=na_sentinel)

# facilitate the properties on the wrapped ops
def _field_accessor(name, docstring=None):
op_accessor = '_{0}'.format(name)
def f(self):
return self._ops_compat(name,op_accessor)

f.__name__ = name
f.__doc__ = docstring
return property(f)

class DatetimeIndexOpsMixin(object):
""" common ops mixin to support a unified inteface datetimelike Index """

def _is_allowed_datetime_index_op(self, name):
if not self._allow_datetime_index_ops:
raise TypeError("cannot perform an {name} operations on this type {typ}".format(
name=name,typ=type(self._get_access_object())))

def _is_allowed_period_index_op(self, name):
if not self._allow_period_index_ops:
raise TypeError("cannot perform an {name} operations on this type {typ}".format(
name=name,typ=type(self._get_access_object())))

def _ops_compat(self, name, op_accessor):

from pandas.tseries.index import DatetimeIndex
from pandas.tseries.period import PeriodIndex
obj = self._get_access_object()
if isinstance(obj, DatetimeIndex):
self._is_allowed_datetime_index_op(name)
elif isinstance(obj, PeriodIndex):
self._is_allowed_period_index_op(name)
try:
return self._wrap_access_object(getattr(obj,op_accessor))
except AttributeError:
raise TypeError("cannot perform an {name} operations on this type {typ}".format(
name=name,typ=type(obj)))

date = _field_accessor('date','Returns numpy array of datetime.date. The date part of the Timestamps')
time = _field_accessor('time','Returns numpy array of datetime.time. The time part of the Timestamps')
year = _field_accessor('year', "The year of the datetime")
Expand Down
17 changes: 15 additions & 2 deletions pandas/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pandas.compat as compat
import pandas as pd
from pandas.compat import u, StringIO
from pandas.core.base import FrozenList, FrozenNDArray
from pandas.core.base import FrozenList, FrozenNDArray, DatetimeIndexOpsMixin
from pandas.util.testing import assertRaisesRegexp, assert_isinstance
from pandas import Series, Index, Int64Index, DatetimeIndex, PeriodIndex
from pandas import _np_version_under1p7
Expand Down Expand Up @@ -181,7 +181,13 @@ def check_ops_properties(self, props, filter=None, ignore_failures=False):
# we mostly care about Series hwere anyhow
if not ignore_failures:
for o in self.not_valid_objs:
self.assertRaises(TypeError, lambda : getattr(o,op))

# an object that is datetimelike will raise a TypeError, otherwise
# an AttributeError
if issubclass(type(o), DatetimeIndexOpsMixin):
self.assertRaises(TypeError, lambda : getattr(o,op))
else:
self.assertRaises(AttributeError, lambda : getattr(o,op))

class TestIndexOps(Ops):

Expand Down Expand Up @@ -462,6 +468,13 @@ def test_ops_properties_basic(self):
for op in ['year','day','second','weekday']:
self.assertRaises(TypeError, lambda x: getattr(self.dt_series,op))

# attribute access should still work!
s = Series(dict(year=2000,month=1,day=10))
self.assertEquals(s.year,2000)
self.assertEquals(s.month,1)
self.assertEquals(s.day,10)
self.assertRaises(AttributeError, lambda : s.weekday)

class TestPeriodIndexOps(Ops):
_allowed = '_allow_period_index_ops'

Expand Down
6 changes: 0 additions & 6 deletions pandas/tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -5617,12 +5617,6 @@ def test_asfreq(self):
self.assertEqual(len(result), 0)
self.assertIsNot(result, ts)

def test_weekday(self):
# Just run the function
def f():
self.ts.weekday
self.assertRaises(TypeError, f)

def test_diff(self):
# Just run the function
self.ts.diff()
Expand Down
3 changes: 2 additions & 1 deletion pandas/tseries/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from pandas.tseries.frequencies import (
infer_freq, to_offset, get_period_alias,
Resolution, get_reso_string, get_offset)
from pandas.core.base import DatetimeIndexOpsMixin
from pandas.tseries.offsets import DateOffset, generate_range, Tick, CDay
from pandas.tseries.tools import parse_time_string, normalize_date
from pandas.util.decorators import cache_readonly
Expand Down Expand Up @@ -102,7 +103,7 @@ def _ensure_datetime64(other):

_midnight = time(0, 0)

class DatetimeIndex(Int64Index):
class DatetimeIndex(DatetimeIndexOpsMixin, Int64Index):
"""
Immutable ndarray of datetime64 data, represented internally as int64, and
which can be boxed to Timestamp objects that are subclasses of datetime and
Expand Down
3 changes: 2 additions & 1 deletion pandas/tseries/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pandas.tseries.frequencies import (get_freq_code as _gfc,
_month_numbers, FreqGroup)
from pandas.tseries.index import DatetimeIndex, Int64Index, Index
from pandas.core.base import DatetimeIndexOpsMixin
from pandas.tseries.tools import parse_time_string
import pandas.tseries.frequencies as _freq_mod

Expand Down Expand Up @@ -500,7 +501,7 @@ def wrapper(self, other):
return wrapper


class PeriodIndex(Int64Index):
class PeriodIndex(DatetimeIndexOpsMixin, Int64Index):
"""
Immutable ndarray holding ordinal values indicating regular periods in
time such as particular years, quarters, months, etc. A value of 1 is the
Expand Down