Skip to content

Commit 4b17314

Browse files
committed
Merge pull request #7206 from jreback/ops
API: remove datetime-like index ops from Series
2 parents ccd593f + ceb6bc0 commit 4b17314

File tree

6 files changed

+31
-48
lines changed

6 files changed

+31
-48
lines changed

doc/source/release.rst

+4-15
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,10 @@ API Changes
8686
- ``df.to_html`` will now print out the header of an empty dataframe (:issue:`6062`)
8787
- The ``interpolate`` ``downcast`` keyword default has been changed from ``infer`` to
8888
``None``. This is to preseve the original dtype unless explicitly requested otherwise (:issue:`6290`).
89-
- allow a Series to utilize index methods depending on its index type, e.g. ``Series.year`` is now defined
90-
for a Series with a ``DatetimeIndex`` or a ``PeriodIndex``; trying this on a non-supported Index type will
91-
now raise a ``TypeError``. (:issue:`4551`, :issue:`4056`, :issue:`5519`)
92-
93-
The following are affected:
94-
95-
- ``date,time,year,month,day``
96-
- ``hour,minute,second,weekofyear``
97-
- ``week,dayofweek,dayofyear,quarter``
98-
- ``microsecond,nanosecond,qyear``
99-
- ``is_month_start,is_month_end``
100-
- ``is_quarter_start,is_quarter_end``
101-
- ``is_year_start,is_year_end``
102-
- ``min(),max()``
103-
- ``pd.infer_freq()``
89+
- allow ``Series`` and ``Index`` to share common ops. remove the ``Series.weekday`` property from Series;
90+
Using a ``DatetimeIndex/PeriodIndex`` method on a Series will now raise a ``TypeError``.
91+
support ``min(),max(),factorize(),unique(),nunique(),value_counts()`` on ``Index`` types.
92+
(:issue:`4551`, :issue:`4056`, :issue:`5519`, :issue:`6380`, :issue:`7206`).
10493

10594
- Add ``is_month_start``, ``is_month_end``, ``is_quarter_start``, ``is_quarter_end``,
10695
``is_year_start``, ``is_year_end`` accessors for ``DateTimeIndex`` / ``Timestamp`` which return a boolean array

doc/source/v0.14.0.txt

+8-26
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,10 @@ API changes
7373
``None``. This is to preseve the original dtype unless explicitly requested otherwise (:issue:`6290`).
7474
- When converting a dataframe to HTML it used to return `Empty DataFrame`. This special case has
7575
been removed, instead a header with the column names is returned (:issue:`6062`).
76-
- allow a Series to utilize index methods depending on its index type, e.g. ``Series.year`` is now defined
77-
for a Series with a ``DatetimeIndex`` or a ``PeriodIndex``; trying this on a non-supported Index type will
78-
now raise a ``TypeError``. (:issue:`4551`, :issue:`4056`, :issue:`5519`)
79-
80-
The following are affected:
81-
82-
- ``date,time,year,month,day``
83-
- ``hour,minute,second,weekofyear``
84-
- ``week,dayofweek,dayofyear,quarter``
85-
- ``microsecond,nanosecond,qyear``
86-
- ``is_month_start,is_month_end``
87-
- ``is_quarter_start,is_quarter_end``
88-
- ``is_year_start,is_year_end``
89-
- ``min(),max()``
90-
- ``pd.infer_freq()``
91-
92-
.. ipython:: python
93-
94-
s = Series(np.random.randn(5),index=tm.makeDateIndex(5))
95-
s
96-
s.year
97-
s.index.year
76+
- allow ``Series`` and ``Index`` to share common ops. remove the ``Series.weekday`` property from Series;
77+
Using a ``DatetimeIndex/PeriodIndex`` method on a Series will now raise a ``TypeError``.
78+
support ``min(),max(),factorize(),unique(),nunique(),value_counts()`` on ``Index`` types.
79+
(:issue:`4551`, :issue:`4056`, :issue:`5519`, :issue:`6380`, :issue:`7206`).
9880

9981
- Add ``is_month_start``, ``is_month_end``, ``is_quarter_start``, ``is_quarter_end``, ``is_year_start``, ``is_year_end`` accessors for ``DateTimeIndex`` / ``Timestamp`` which return a boolean array of whether the timestamp(s) are at the start/end of the month/quarter/year defined by the frequency of the ``DateTimeIndex`` / ``Timestamp`` (:issue:`4565`, :issue:`6998`)
10082

@@ -355,7 +337,7 @@ are introduced. The function :func:`~pandas.read_sql` is kept as a convenience
355337
wrapper around the other two and will delegate to specific function depending on
356338
the provided input (database table name or sql query).
357339

358-
In practice, you have to provide a SQLAlchemy ``engine`` to the sql functions.
340+
In practice, you have to provide a SQLAlchemy ``engine`` to the sql functions.
359341
To connect with SQLAlchemy you use the :func:`create_engine` function to create an engine
360342
object from database URI. You only need to create the engine once per database you are
361343
connecting to. For an in-memory sqlite database:
@@ -384,7 +366,7 @@ or by specifying a sql query:
384366
.. ipython:: python
385367

386368
pd.read_sql_query('SELECT * FROM db_table', engine)
387-
369+
388370
Some other enhancements to the sql functions include:
389371

390372
- support for writing the index. This can be controlled with the ``index``
@@ -397,7 +379,7 @@ Some other enhancements to the sql functions include:
397379

398380
Some of the existing functions or function aliases have been deprecated
399381
and will be removed in future versions. This includes: ``tquery``, ``uquery``,
400-
``read_frame``, ``frame_query``, ``write_frame``.
382+
``read_frame``, ``frame_query``, ``write_frame``.
401383

402384
.. warning::
403385

@@ -638,7 +620,7 @@ Deprecations
638620
- The support for the 'mysql' flavor when using DBAPI connection objects has been deprecated.
639621
MySQL will be further supported with SQLAlchemy engines (:issue:`6900`).
640622

641-
- The following ``io.sql`` functions have been deprecated: ``tquery``, ``uquery``, ``read_frame``, ``frame_query``, ``write_frame``.
623+
- The following ``io.sql`` functions have been deprecated: ``tquery``, ``uquery``, ``read_frame``, ``frame_query``, ``write_frame``.
642624

643625
- The `percentile_width` keyword argument in :meth:`~DataFrame.describe` has been deprecated.
644626
Use the `percentiles` keyword instead, which takes a list of percentiles to display. The

pandas/core/base.py

-2
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,10 @@ def _wrap_access_object(self, obj):
261261

262262
def max(self):
263263
""" The maximum value of the object """
264-
self._is_allowed_index_op('max')
265264
return self.values.max()
266265

267266
def min(self):
268267
""" The minimum value of the object """
269-
self._is_allowed_index_op('min')
270268
return self.values.min()
271269

272270
def value_counts(self, normalize=False, sort=True, ascending=False,

pandas/core/series.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,15 @@ class Series(base.IndexOpsMixin, generic.NDFrame):
121121

122122
@property
123123
def _allow_datetime_index_ops(self):
124-
return self.index.is_all_dates and isinstance(self.index, DatetimeIndex)
124+
# disabling to invalidate datetime index ops (GH7206)
125+
# return self.index.is_all_dates and isinstance(self.index, DatetimeIndex)
126+
return False
125127

126128
@property
127129
def _allow_period_index_ops(self):
128-
return self.index.is_all_dates and isinstance(self.index, PeriodIndex)
130+
# disabling to invalidate period index ops (GH7206)
131+
# return self.index.is_all_dates and isinstance(self.index, PeriodIndex)
132+
return False
129133

130134
def __init__(self, data=None, index=None, dtype=None, name=None,
131135
copy=False, fastpath=False):

pandas/tests/test_base.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,15 @@ def setUp(self):
452452

453453
def test_ops_properties(self):
454454
self.check_ops_properties(['year','month','day','hour','minute','second','weekofyear','week','dayofweek','dayofyear','quarter'])
455-
self.check_ops_properties(['date','time','microsecond','nanosecond', 'is_month_start', 'is_month_end', 'is_quarter_start', 'is_quarter_end', 'is_year_start', 'is_year_end'], lambda x: isinstance(x,DatetimeIndex))
455+
self.check_ops_properties(['date','time','microsecond','nanosecond', 'is_month_start', 'is_month_end', 'is_quarter_start',
456+
'is_quarter_end', 'is_year_start', 'is_year_end'], lambda x: isinstance(x,DatetimeIndex))
457+
458+
def test_ops_properties_basic(self):
459+
460+
# sanity check that the behavior didn't change
461+
# GH7206
462+
for op in ['year','day','second','weekday']:
463+
self.assertRaises(TypeError, lambda x: getattr(self.dt_series,op))
456464

457465
class TestPeriodIndexOps(Ops):
458466
_allowed = '_allow_period_index_ops'

pandas/tests/test_series.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -5619,7 +5619,9 @@ def test_asfreq(self):
56195619

56205620
def test_weekday(self):
56215621
# Just run the function
5622-
weekdays = self.ts.weekday
5622+
def f():
5623+
self.ts.weekday
5624+
self.assertRaises(TypeError, f)
56235625

56245626
def test_diff(self):
56255627
# Just run the function
@@ -5715,7 +5717,7 @@ def test_select(self):
57155717
assert_series_equal(result, expected)
57165718

57175719
result = self.ts.select(lambda x: x.weekday() == 2)
5718-
expected = self.ts[self.ts.weekday == 2]
5720+
expected = self.ts[self.ts.index.weekday == 2]
57195721
assert_series_equal(result, expected)
57205722

57215723
#------------------------------------------------------------------------------

0 commit comments

Comments
 (0)