Skip to content

Commit ee6262d

Browse files
committed
ENH: deprecate timeRule and offset in shift method, clean up cython build
1 parent 14a58b6 commit ee6262d

11 files changed

+101
-82
lines changed

pandas/core/frame.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -2849,7 +2849,7 @@ def diff(self, periods=1):
28492849
"""
28502850
return self - self.shift(periods)
28512851

2852-
def shift(self, periods, offset=None, **kwds):
2852+
def shift(self, periods, freq=None, **kwds):
28532853
"""
28542854
Shift the index of the DataFrame by desired number of periods with an
28552855
optional time offset
@@ -2868,13 +2868,23 @@ def shift(self, periods, offset=None, **kwds):
28682868
if periods == 0:
28692869
return self
28702870

2871-
offset = kwds.get('timeRule', offset)
2872-
if isinstance(offset, basestring):
2873-
# deprecated code path
2874-
if isinstance(self.index, DateRange):
2871+
if 'timeRule' in kwds or 'offset' in kwds:
2872+
offset = kwds.get('offset')
2873+
offset = kwds.get('timeRule', offset)
2874+
if isinstance(offset, basestring):
28752875
offset = datetools.getOffset(offset)
2876-
else:
2877-
offset = datetools.to_offset(offset)
2876+
warn = True
2877+
else:
2878+
offset = freq
2879+
warn = False
2880+
2881+
if warn:
2882+
import warnings
2883+
warnings.warn("'timeRule' and 'offset' parameters are deprecated,"
2884+
" please use 'freq' instead", FutureWarning)
2885+
2886+
if isinstance(offset, basestring):
2887+
offset = datetools.to_offset(offset)
28782888

28792889
def _shift_block(blk, indexer):
28802890
new_values = blk.values.take(indexer, axis=1)

pandas/core/index.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,10 @@ def __new__(cls, data=None,
11251125
_deprecated=False, **kwds):
11261126

11271127
if isinstance(offset, basestring):
1128-
offset = datetools.getOffset(offset, _deprecated=_deprecated)
1128+
if _deprecated:
1129+
offset = datetools.getOffset(offset)
1130+
else:
1131+
offset = datetools.to_offset(offset)
11291132

11301133
if data is None and offset is None:
11311134
raise ValueError("Must provide offset argument if no data is "

pandas/core/series.py

+19-11
Original file line numberDiff line numberDiff line change
@@ -2236,7 +2236,7 @@ def last_valid_index(self):
22362236
#----------------------------------------------------------------------
22372237
# Time series-oriented methods
22382238

2239-
def shift(self, periods, offset=None, **kwds):
2239+
def shift(self, periods, freq=None, **kwds):
22402240
"""
22412241
Shift the index of the Series by desired number of periods with an
22422242
optional time offset
@@ -2245,7 +2245,7 @@ def shift(self, periods, offset=None, **kwds):
22452245
----------
22462246
periods : int
22472247
Number of periods to move, can be positive or negative
2248-
offset : DateOffset, timedelta, or time rule string, optional
2248+
freq : DateOffset, timedelta, or time rule string, optional
22492249
Increment to use from datetools module or time rule (e.g. 'EOM')
22502250
22512251
Returns
@@ -2255,13 +2255,23 @@ def shift(self, periods, offset=None, **kwds):
22552255
if periods == 0:
22562256
return self.copy()
22572257

2258-
offset = kwds.get('timeRule', offset)
2259-
if isinstance(offset, basestring):
2260-
# deprecated code path
2261-
if isinstance(self.index, DateRange):
2258+
if 'timeRule' in kwds or 'offset' in kwds:
2259+
offset = kwds.get('offset')
2260+
offset = kwds.get('timeRule', offset)
2261+
if isinstance(offset, basestring):
22622262
offset = datetools.getOffset(offset)
2263-
else:
2264-
offset = datetools.to_offset(offset)
2263+
warn = True
2264+
else:
2265+
offset = freq
2266+
warn = False
2267+
2268+
if warn:
2269+
import warnings
2270+
warnings.warn("'timeRule' and 'offset' parameters are deprecated,"
2271+
" please use 'freq' instead", FutureWarning)
2272+
2273+
if isinstance(offset, basestring):
2274+
offset = datetools.to_offset(offset)
22652275

22662276
if offset is None:
22672277
new_values = np.empty(len(self), dtype=self.dtype)
@@ -2326,7 +2336,7 @@ def asfreq(self, freq, method=None):
23262336
23272337
Parameters
23282338
----------
2329-
offset : DateOffset object, or corresponding string
2339+
freq : DateOffset object, or corresponding string
23302340
DateOffset object or subclass (e.g. monthEnd)
23312341
method : {'backfill', 'pad', None}
23322342
Method to use for filling holes in new index
@@ -2336,8 +2346,6 @@ def asfreq(self, freq, method=None):
23362346
converted : TimeSeries
23372347
"""
23382348

2339-
# TODO: this uses deprecated API, add new method?
2340-
23412349
if isinstance(freq, datetools.DateOffset):
23422350
dateRange = DateRange(self.index[0], self.index[-1], offset=freq)
23432351
else:

pandas/src/datetime.pyx

+18-18
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ from datetime cimport *
1414
from util cimport is_integer_object, is_datetime64_object
1515

1616
# initialize numpy
17-
np.import_array()
18-
np.import_ufunc()
17+
import_array()
18+
import_ufunc()
1919

2020
# import datetime C API
2121
PyDateTime_IMPORT
@@ -199,22 +199,22 @@ cdef convert_to_tsobject(object ts, object tzinfo=None):
199199

200200
return retval
201201

202-
cdef convert_to_res(object res):
203-
if res == 'microsecond':
204-
return r_microsecond
205-
if res == 'second':
206-
return r_second
207-
if res == 'minute':
208-
return r_minute
209-
if res == 'hour':
210-
return r_hour
211-
if res == 'day':
212-
return r_day
213-
if res == 'month':
214-
return r_month
215-
if res == 'year':
216-
return r_year
217-
return r_invalid
202+
#cdef convert_to_res(object res):
203+
# if res == 'microsecond':
204+
# return r_microsecond
205+
# if res == 'second':
206+
# return r_second
207+
# if res == 'minute':
208+
# return r_minute
209+
# if res == 'hour':
210+
# return r_hour
211+
# if res == 'day':
212+
# return r_day
213+
# if res == 'month':
214+
# return r_month
215+
# if res == 'year':
216+
# return r_year
217+
# return r_invalid
218218

219219
cdef conversion_factor(time_res res1, time_res res2):
220220
cdef:

pandas/src/groupby.pyx

+19-19
Original file line numberDiff line numberDiff line change
@@ -452,25 +452,25 @@ def generate_bins_dt64(ndarray[int64_t] values, ndarray[int64_t] binner,
452452

453453
return bins, labels
454454

455-
@cython.boundscheck(False)
456-
@cython.wraparound(False)
457-
cdef ndarray[int32_t] counts_by_bins(ndarray[int32_t] bins,
458-
Py_ssize_t datalen):
459-
cdef:
460-
Py_ssize_t ngroups = len(bins)
461-
i = 0
462-
463-
counts = np.zeros(ngroups, dtype='i4')
464-
465-
if ngroups > 0:
466-
counts[0] = bins[0]
467-
for i in range(1, ngroups):
468-
if i == ngroups - 1:
469-
counts[i] = datalen - bins[i-1]
470-
else:
471-
counts[i] = bins[i] - bins[i-1]
472-
473-
return counts
455+
#@cython.boundscheck(False)
456+
#@cython.wraparound(False)
457+
#cdef ndarray[int32_t] counts_by_bins(ndarray[int32_t] bins,
458+
# Py_ssize_t datalen):
459+
# cdef:
460+
# Py_ssize_t ngroups = len(bins)
461+
# i = 0
462+
463+
# counts = np.zeros(ngroups, dtype='i4')
464+
465+
# if ngroups > 0:
466+
# counts[0] = bins[0]
467+
# for i in range(1, ngroups):
468+
# if i == ngroups - 1:
469+
# counts[i] = datalen - bins[i-1]
470+
# else:
471+
# counts[i] = bins[i] - bins[i-1]
472+
473+
# return counts
474474

475475
# add passing bin edges, instead of labels
476476

pandas/src/np_datetime.c

+13-7
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,15 @@
44
* See NP_LICENSE.txt
55
*/
66

7-
#include <Python.h>
8-
#include <datetime.h>
7+
#define NO_IMPORT
98

9+
#include <Python.h>
1010
#include <time.h>
11-
12-
#include <numpy/arrayobject.h>
1311
#include <numpy/ndarrayobject.h>
14-
15-
#include "numpy/arrayscalars.h"
1612
#include "np_datetime.h"
1713

1814
/* Exported as DATETIMEUNITS in multiarraymodule.c */
19-
static char *_datetime_strings[NPY_DATETIME_NUMUNITS] = {
15+
char *_datetime_strings[NPY_DATETIME_NUMUNITS] = {
2016
NPY_STR_Y,
2117
NPY_STR_M,
2218
NPY_STR_W,
@@ -33,6 +29,16 @@ static char *_datetime_strings[NPY_DATETIME_NUMUNITS] = {
3329
"generic"
3430
};
3531

32+
int _days_per_month_table[2][12] = {
33+
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
34+
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
35+
};
36+
37+
int _month_offset[2][13] = {
38+
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
39+
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
40+
};
41+
3642
/*
3743
* Returns 1 if the given year is a leap year, 0 otherwise.
3844
*/

pandas/src/np_datetime.h

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*
2-
* This is derived from numpy 1.7
2+
* This is derived from numpy 1.7
33
* See NP_LICENSE.TXT
44
*/
55

66
#ifndef _PANDAS_DATETIME_H_
77
#define _PANDAS_DATETIME_H_
88

9-
#define NPY_DATETIME_MAX_ISO8601_STRLEN (21+3*5+1+3*6+6+1)
9+
#define NPY_DATETIME_MAX_ISO8601_STRLEN (21+3*5+1+3*6+6+1)
1010

1111
// stuff pandas needs
1212
// ----------------------------------------------------------------------------
@@ -19,23 +19,17 @@ int convert_pydatetime_to_datetimestruct(PyObject *obj, npy_datetimestruct *out,
1919
int dayofweek(int y, int m, int d);
2020

2121
/* Days per month, regular year and leap year */
22-
static int _days_per_month_table[2][12] = {
23-
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
24-
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
25-
};
22+
int _days_per_month_table[2][12];
2623

2724
/* Table with day offsets for each month (0-based, without and with leap) */
28-
static int _month_offset[2][13] = {
29-
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
30-
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
31-
};
25+
int _month_offset[2][13];
3226

3327
// stuff numpy needs in header
3428
// ----------------------------------------------------------------------------
3529

3630
int is_leapyear(npy_int64 year);
3731

38-
static char *_datetime_strings[NPY_DATETIME_NUMUNITS];
32+
char *_datetime_strings[NPY_DATETIME_NUMUNITS];
3933

4034
/*
4135
* Converts a datetime from a datetimestruct to a datetime based

pandas/src/np_datetime_strings.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@
88
*/
99

1010
#define PY_SSIZE_T_CLEAN
11+
#define NO_IMPORT
12+
1113
#include <Python.h>
1214

1315
#include <time.h>
1416

1517
#include <numpy/arrayobject.h>
16-
17-
//#include "numpy/npy_3kcompat.h"
18-
1918
#include "numpy/arrayscalars.h"
2019

2120
#include "np_datetime.h"

pandas/tests/test_daterange.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ def test_constructor(self):
5858
def test_cached_range(self):
5959
rng = DateRange._cached_range(START, END, offset=datetools.bday)
6060
rng = DateRange._cached_range(START, periods=20, offset=datetools.bday)
61-
rng = DateRange._cached_range(end=START, periods=20,
62-
offset=datetools.bday)
61+
rng = DateRange._cached_range(end=START, periods=20, offset=datetools.bday)
6362

6463
self.assertRaises(Exception, DateRange._cached_range, START, END)
6564

pandas/tests/test_frame.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3379,7 +3379,7 @@ def test_shift(self):
33793379
shiftedFrame = self.tsframe.shift(5, offset=datetools.BDay())
33803380
self.assert_(len(shiftedFrame) == len(self.tsframe))
33813381

3382-
shiftedFrame2 = self.tsframe.shift(5, timeRule='B')
3382+
shiftedFrame2 = self.tsframe.shift(5, timeRule='WEEKDAY')
33833383
assert_frame_equal(shiftedFrame, shiftedFrame2)
33843384

33853385
d = self.tsframe.index[0]

pandas/tests/test_series.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1645,8 +1645,8 @@ def test_shift(self):
16451645
unshifted = self.ts.shift(0, offset=offset)
16461646
assert_series_equal(unshifted, self.ts)
16471647

1648-
shifted = self.ts.shift(1, timeRule='B')
1649-
unshifted = shifted.shift(-1, timeRule='B')
1648+
shifted = self.ts.shift(1, timeRule='WEEKDAY')
1649+
unshifted = shifted.shift(-1, timeRule='WEEKDAY')
16501650

16511651
assert_series_equal(unshifted, self.ts)
16521652

0 commit comments

Comments
 (0)