Skip to content

Commit 300a895

Browse files
committed
Merge pull request #5244 from jreback/truncate
API/CLN: consolidate truncate into NDFrame (panel had a separate method)
2 parents 6830600 + 152277a commit 300a895

File tree

6 files changed

+32
-32
lines changed

6 files changed

+32
-32
lines changed

doc/source/release.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ API Changes
314314
- Provide __dir__ method (and local context) for tab completion / remove ipython completers code
315315
(:issue:`4501`)
316316
- Support non-unique axes in a Panel via indexing operations (:issue:`4960`)
317+
- ``.truncate`` will raise a ``ValueError`` if invalid before and afters dates are given (:issue:`5242`)
317318

318319
Internal Refactoring
319320
~~~~~~~~~~~~~~~~~~~~

pandas/core/generic.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,7 +2813,7 @@ def tshift(self, periods=1, freq=None, axis=0, **kwds):
28132813

28142814
return self._constructor(new_data).__finalize__(self)
28152815

2816-
def truncate(self, before=None, after=None, copy=True):
2816+
def truncate(self, before=None, after=None, axis=None, copy=True):
28172817
"""Truncates a sorted NDFrame before and/or after some particular
28182818
dates.
28192819
@@ -2823,28 +2823,38 @@ def truncate(self, before=None, after=None, copy=True):
28232823
Truncate before date
28242824
after : date
28252825
Truncate after date
2826+
axis : the truncation axis, defaults to the stat axis
2827+
copy : boolean, default is True,
2828+
return a copy of the truncated section
28262829
28272830
Returns
28282831
-------
28292832
truncated : type of caller
28302833
"""
28312834

2835+
if axis is None:
2836+
axis = self._stat_axis_number
2837+
axis = self._get_axis_number(axis)
2838+
ax = self._get_axis(axis)
2839+
28322840
# if we have a date index, convert to dates, otherwise
28332841
# treat like a slice
2834-
if self.index.is_all_dates:
2842+
if ax.is_all_dates:
28352843
from pandas.tseries.tools import to_datetime
28362844
before = to_datetime(before)
28372845
after = to_datetime(after)
28382846

28392847
if before is not None and after is not None:
28402848
if before > after:
2841-
raise AssertionError('Truncate: %s must be after %s' %
2842-
(after, before))
2849+
raise ValueError('Truncate: %s must be after %s' %
2850+
(after, before))
28432851

2844-
result = self.ix[before:after]
2852+
slicer = [ slice(None, None) ] * self._AXIS_LEN
2853+
slicer[axis] = slice(before,after)
2854+
result = self.ix[tuple(slicer)]
28452855

2846-
if isinstance(self.index, MultiIndex):
2847-
result.index = self.index.truncate(before, after)
2856+
if isinstance(ax, MultiIndex):
2857+
setattr(result,self._get_axis_name(axis),ax.truncate(before, after))
28482858

28492859
if copy:
28502860
result = result.copy()

pandas/core/panel.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -998,30 +998,6 @@ def shift(self, lags, freq=None, axis='major'):
998998
def tshift(self, periods=1, freq=None, axis='major', **kwds):
999999
return super(Panel, self).tshift(periods, freq, axis, **kwds)
10001000

1001-
def truncate(self, before=None, after=None, axis='major'):
1002-
"""Function truncates a sorted Panel before and/or after some
1003-
particular values on the requested axis
1004-
1005-
Parameters
1006-
----------
1007-
before : date
1008-
Left boundary
1009-
after : date
1010-
Right boundary
1011-
axis : {'major', 'minor', 'items'}
1012-
1013-
Returns
1014-
-------
1015-
Panel
1016-
"""
1017-
axis = self._get_axis_name(axis)
1018-
index = self._get_axis(axis)
1019-
1020-
beg_slice, end_slice = index.slice_locs(before, after)
1021-
new_index = index[beg_slice:end_slice]
1022-
1023-
return self.reindex(**{axis: new_index})
1024-
10251001
def join(self, other, how='left', lsuffix='', rsuffix=''):
10261002
"""
10271003
Join items with other Panel either on major and minor axes column

pandas/sparse/panel.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ def _ixs(self, i, axis=0):
187187

188188
return self.xs(key, axis=axis)
189189

190+
def _slice(self, slobj, axis=0, raise_on_error=False, typ=None):
191+
"""
192+
for compat as we don't support Block Manager here
193+
"""
194+
axis = self._get_axis_name(axis)
195+
index = self._get_axis(axis)
196+
197+
return self.reindex(**{axis: index[slobj]})
198+
190199
def _get_item_cache(self, key):
191200
return self._frames[key]
192201

pandas/tests/test_frame.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7731,6 +7731,10 @@ def test_truncate(self):
77317731
truncated = ts.truncate(after=end_missing)
77327732
assert_frame_equal(truncated, expected)
77337733

7734+
self.assertRaises(ValueError, ts.truncate,
7735+
before=ts.index[-1] - 1,
7736+
after=ts.index[0] +1)
7737+
77347738
def test_truncate_copy(self):
77357739
index = self.tsframe.index
77367740
truncated = self.tsframe.truncate(index[5], index[10])

pandas/tests/test_series.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3899,7 +3899,7 @@ def test_truncate(self):
38993899
truncated = ts.truncate(before=self.ts.index[-1] + offset)
39003900
assert(len(truncated) == 0)
39013901

3902-
self.assertRaises(Exception, ts.truncate,
3902+
self.assertRaises(ValueError, ts.truncate,
39033903
before=self.ts.index[-1] + offset,
39043904
after=self.ts.index[0] - offset)
39053905

0 commit comments

Comments
 (0)