Skip to content

Commit dfb6e90

Browse files
committed
ENH: added strftime, working to adapt tsplot.py for IntervalIndex
1 parent eb36ebf commit dfb6e90

File tree

7 files changed

+1440
-32
lines changed

7 files changed

+1440
-32
lines changed

pandas/core/datetools.py

+12
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ def __init__(self, value=None, freq=None,
233233
self.freq = (base, mult)
234234
elif isinstance(freq, tuple):
235235
self.freq = freq
236+
elif isinstance(freq, (int, long)):
237+
self.freq = (freq, 1)
236238
else:
237239
raise ValueError("Expected (timerule, mult) tuple for freq")
238240

@@ -425,6 +427,14 @@ def __str__(self):
425427
formatted = lib.skts_ordinal_to_string(self.ordinal, base, mult)
426428
return ("%s" % formatted)
427429

430+
def strftime(self, fmt):
431+
base = self.freq[0]
432+
mult = self.freq[1]
433+
if fmt is not None:
434+
return lib.skts_strftime(self.ordinal, base, mult, fmt)
435+
else:
436+
return lib.skts_ordinal_to_string(self.ordinal, base, mult)
437+
428438
def _infer_interval_group(freqstr):
429439
return _interval_group(_reso_interval_map[freqstr])
430440

@@ -433,6 +443,8 @@ def _interval_group(freqstr):
433443
return base // 1000 * 1000
434444

435445
def _get_freq_code(freqstr):
446+
if isinstance(freqstr, tuple):
447+
return freqstr
436448
base, stride = _base_and_stride(freqstr)
437449
code = _interval_code_map[base]
438450
return code, stride

pandas/core/index.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,9 @@ def __new__(cls, data=None,
18801880
raise ValueError("Must provide freq argument if no data is "
18811881
"supplied")
18821882

1883+
if isinstance(freq, (int, long)):
1884+
freq = datetools._reverse_interval_code_map[freq]
1885+
18831886
if data is None:
18841887
start = to_interval(start, freq)
18851888
end = to_interval(end, freq)
@@ -1896,11 +1899,11 @@ def __new__(cls, data=None,
18961899
else:
18971900
data = np.arange(start.ordinal, end.ordinal+1, dtype=np.int64)
18981901

1899-
index = data.view(cls)
1900-
index.name = name
1901-
index.freq = freq
1902+
subarr = data.view(cls)
1903+
subarr.name = name
1904+
subarr.freq = freq
19021905

1903-
return index
1906+
return subarr
19041907

19051908
if not isinstance(data, np.ndarray):
19061909
if np.isscalar(data):
@@ -2071,6 +2074,21 @@ def shift(self, n):
20712074

20722075
return IntervalIndex(data=self.values + n, freq=self.freq)
20732076

2077+
def __add__(self, other):
2078+
if isinstance(other, (int, long)):
2079+
return IntervalIndex(self.values + other, self.freq)
2080+
return super(IntervalIndex, self).__add__(other)
2081+
2082+
def __sub__(self, other):
2083+
if isinstance(other, (int, long)):
2084+
return IntervalIndex(self.values - other, self.freq)
2085+
if isinstance(other, Interval):
2086+
if other.freq != self.freq:
2087+
raise ValueError("Cannot do arithmetic with "
2088+
"non-conforming intervals")
2089+
return IntervalIndex(self.values - other.ordinal)
2090+
return super(IntervalIndex, self).__sub__(other)
2091+
20742092
@property
20752093
def inferred_type(self):
20762094
# b/c data is represented as ints make sure we can't have ambiguous

pandas/src/datetime.pxd

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ cdef extern from "skts.h":
117117

118118
PyObject *interval_strftime(long value, int freq, PyObject *args)
119119
PyObject *interval_to_string(long value, int freq)
120+
PyObject *interval_to_string2(long value, int freq, char *fmt)
120121

121122
int get_date_info(long ordinal, int freq, date_info *dinfo) except -1
122123

pandas/src/datetime.pyx

+40-28
Original file line numberDiff line numberDiff line change
@@ -554,34 +554,34 @@ cdef class DayOffset(_Offset):
554554
self.t += (4 - self.dow) * us_in_day
555555
self.dow = 4
556556

557-
cdef ndarray[int64_t] _generate_range(_Offset offset, Py_ssize_t periods):
558-
"""
559-
Generate timestamps according to offset.
560-
"""
561-
cdef:
562-
Py_ssize_t i
563-
ndarray[int64_t] dtindex
564-
565-
dtindex = np.empty(periods, np.int64)
566-
for i in range(periods):
567-
dtindex[i] = offset._ts()
568-
offset.next()
569-
return dtindex
570-
571-
cdef int64_t _count_range(_Offset offset, object end):
572-
"""
573-
Count timestamps in range according to offset up to (and including)
574-
end time.
575-
"""
576-
cdef:
577-
Py_ssize_t i=0
578-
_TSObject e
579-
580-
e = convert_to_tsobject(end)
581-
while offset._ts() <= e.value:
582-
i += 1
583-
offset.next()
584-
return i
557+
#cdef ndarray[int64_t] _generate_range(_Offset offset, Py_ssize_t periods):
558+
# """
559+
# Generate timestamps according to offset.
560+
# """
561+
# cdef:
562+
# Py_ssize_t i
563+
# ndarray[int64_t] dtindex
564+
565+
# dtindex = np.empty(periods, np.int64)
566+
# for i in range(periods):
567+
# dtindex[i] = offset._ts()
568+
# offset.next()
569+
# return dtindex
570+
571+
#cdef int64_t _count_range(_Offset offset, object end):
572+
# """
573+
# Count timestamps in range according to offset up to (and including)
574+
# end time.
575+
# """
576+
# cdef:
577+
# Py_ssize_t i=0
578+
# _TSObject e
579+
580+
# e = convert_to_tsobject(end)
581+
# while offset._ts() <= e.value:
582+
# i += 1
583+
# offset.next()
584+
# return i
585585

586586
# Conversion routines
587587
# ------------------------------------------------------------------------------
@@ -1023,6 +1023,18 @@ cpdef int64_t skts_ordinal_to_dt64(long skts_ordinal, int base, long mult):
10231023
def skts_ordinal_to_string(long value, int base, long mult):
10241024
return <object>interval_to_string(remove_mult(value, mult), base)
10251025

1026+
def skts_strftime(long value, int freq, long mult, object fmt):
1027+
cdef:
1028+
PyObject *ptr
1029+
1030+
value = remove_mult(value, mult)
1031+
ptr = interval_to_string2(value, freq, <char*>fmt)
1032+
1033+
if ptr == NULL:
1034+
raise ValueError("Could not create string with fmt '%s'" % fmt)
1035+
1036+
return <object>ptr
1037+
10261038
# interval accessors
10271039

10281040
ctypedef int (*accessor)(long ordinal, int base) except -1

pandas/src/skts.c

+10
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,16 @@ PyObject *interval_to_string(long value, int freq)
12841284
return retval;
12851285
}
12861286

1287+
PyObject *interval_to_string2(long value, int freq, char *fmt)
1288+
{
1289+
PyObject *string_arg, *retval;
1290+
string_arg = Py_BuildValue("(s)", fmt);
1291+
if (string_arg == NULL) { return NULL; }
1292+
retval = interval_strftime(value, freq, string_arg);
1293+
Py_DECREF(string_arg);
1294+
return retval;
1295+
}
1296+
12871297
static int _quarter_year(long ordinal, int freq, int *year, int *quarter) {
12881298
asfreq_info af_info;
12891299
int qtr_freq;

pandas/src/skts.h

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ long get_python_ordinal(long skts_ordinal, int freq);
160160

161161
PyObject *interval_strftime(long value, int freq, PyObject *args);
162162
PyObject *interval_to_string(long value, int freq);
163+
PyObject *interval_to_string2(long value, int freq, char *fmt);
163164

164165
int get_date_info(long ordinal, int freq, struct date_info *dinfo);
165166

0 commit comments

Comments
 (0)