Skip to content
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

Tslibs resolution #18034

Merged
merged 24 commits into from
Nov 13, 2017
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c8cb176
implement tslibs.resolution
jbrockmendel Oct 26, 2017
757321d
flake cleanup
jbrockmendel Oct 26, 2017
98e612f
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Oct 29, 2017
4b6080d
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Oct 30, 2017
58ced56
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Oct 31, 2017
1ae12c6
update imports
jbrockmendel Nov 1, 2017
1507a7f
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 1, 2017
7404b13
dummy commit to force CI re-run
jbrockmendel Nov 1, 2017
9b8c61c
edits per reviewer suggestions
jbrockmendel Nov 1, 2017
c9bf005
remove unused; update imports; add whatsnew note
jbrockmendel Nov 2, 2017
4817941
name fixup
jbrockmendel Nov 2, 2017
25ef9b2
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 3, 2017
9c17366
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 5, 2017
cd34cdc
whitespace cleanup
jbrockmendel Nov 5, 2017
1868634
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 7, 2017
c3c4cae
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 7, 2017
d939e5c
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 8, 2017
096a5af
Edits per reviewer requests
jbrockmendel Nov 8, 2017
5701c5e
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 8, 2017
46d6551
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 9, 2017
b8b0124
edits per reviewer comments
jbrockmendel Nov 9, 2017
219884e
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 12, 2017
0ab2b08
whatsnew edit per request
jbrockmendel Nov 12, 2017
7b374d3
Merge branch 'master' of https://github.com/pandas-dev/pandas into ts…
jbrockmendel Nov 13, 2017
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
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.22.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Other API Changes
- :class:`Timestamp` will no longer silently ignore unused or invalid `tz` or `tzinfo` keyword arguments (:issue:`17690`)
- :class:`Timestamp` will no longer silently ignore invalid `freq` arguments (:issue:`5168`)
- :class:`CacheableOffset` and :class:`WeekDay` are no longer available in the `tseries.offsets` module (:issue:`17830`)

- :function:`tseries.frequencies.get_freq_group` and :list:`tseries.frequencies.DAYS` are removed from the private API (:issue:`18034`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private -> public

.. _whatsnew_0220.deprecations:

Deprecations
Expand Down
112 changes: 10 additions & 102 deletions pandas/_libs/period.pyx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# cython: profile=False
from datetime import datetime, date, timedelta
import operator

Expand Down Expand Up @@ -27,28 +28,23 @@ from util cimport is_period_object, is_string_object, INT32_MIN

from lib cimport is_null_datetimelike
from pandas._libs import tslib
from pandas._libs.tslib import Timestamp, iNaT, NaT
from pandas._libs.tslib import Timestamp, iNaT
from tslibs.timezones cimport (
is_utc, is_tzlocal, get_utcoffset, get_dst_info, maybe_get_tz)
from tslibs.timedeltas cimport delta_to_nanoseconds

from tslibs.parsing import parse_time_string, NAT_SENTINEL
from tslibs.parsing import (parse_time_string, NAT_SENTINEL,
_get_rule_month, _MONTH_NUMBERS)
from tslibs.frequencies cimport get_freq_code
from tslibs.nattype import nat_strings
from tslibs.resolution import resolution, Resolution
from tslibs.nattype import nat_strings, NaT
from tslibs.nattype cimport _nat_scalar_rules

from pandas.tseries import offsets
from pandas.tseries import frequencies

cdef int64_t NPY_NAT = util.get_nat()

cdef int RESO_US = frequencies.RESO_US
cdef int RESO_MS = frequencies.RESO_MS
cdef int RESO_SEC = frequencies.RESO_SEC
cdef int RESO_MIN = frequencies.RESO_MIN
cdef int RESO_HR = frequencies.RESO_HR
cdef int RESO_DAY = frequencies.RESO_DAY

cdef extern from "period_helper.h":
ctypedef struct date_info:
int64_t absdate
Expand Down Expand Up @@ -487,98 +483,10 @@ def extract_freq(ndarray[object] values):
raise ValueError('freq not specified and cannot be inferred')


cpdef resolution(ndarray[int64_t] stamps, tz=None):
cdef:
Py_ssize_t i, n = len(stamps)
pandas_datetimestruct dts
int reso = RESO_DAY, curr_reso

if tz is not None:
tz = maybe_get_tz(tz)
return _reso_local(stamps, tz)
else:
for i in range(n):
if stamps[i] == NPY_NAT:
continue
dt64_to_dtstruct(stamps[i], &dts)
curr_reso = _reso_stamp(&dts)
if curr_reso < reso:
reso = curr_reso
return reso


cdef inline int _reso_stamp(pandas_datetimestruct *dts):
if dts.us != 0:
if dts.us % 1000 == 0:
return RESO_MS
return RESO_US
elif dts.sec != 0:
return RESO_SEC
elif dts.min != 0:
return RESO_MIN
elif dts.hour != 0:
return RESO_HR
return RESO_DAY

cdef _reso_local(ndarray[int64_t] stamps, object tz):
cdef:
Py_ssize_t n = len(stamps)
int reso = RESO_DAY, curr_reso
ndarray[int64_t] trans, deltas, pos
pandas_datetimestruct dts

if is_utc(tz):
for i in range(n):
if stamps[i] == NPY_NAT:
continue
dt64_to_dtstruct(stamps[i], &dts)
curr_reso = _reso_stamp(&dts)
if curr_reso < reso:
reso = curr_reso
elif is_tzlocal(tz):
for i in range(n):
if stamps[i] == NPY_NAT:
continue
dt64_to_dtstruct(stamps[i], &dts)
dt = datetime(dts.year, dts.month, dts.day, dts.hour,
dts.min, dts.sec, dts.us, tz)
delta = int(get_utcoffset(tz, dt).total_seconds()) * 1000000000
dt64_to_dtstruct(stamps[i] + delta, &dts)
curr_reso = _reso_stamp(&dts)
if curr_reso < reso:
reso = curr_reso
else:
# Adjust datetime64 timestamp, recompute datetimestruct
trans, deltas, typ = get_dst_info(tz)

_pos = trans.searchsorted(stamps, side='right') - 1
if _pos.dtype != np.int64:
_pos = _pos.astype(np.int64)
pos = _pos

# statictzinfo
if typ not in ['pytz', 'dateutil']:
for i in range(n):
if stamps[i] == NPY_NAT:
continue
dt64_to_dtstruct(stamps[i] + deltas[0], &dts)
curr_reso = _reso_stamp(&dts)
if curr_reso < reso:
reso = curr_reso
else:
for i in range(n):
if stamps[i] == NPY_NAT:
continue
dt64_to_dtstruct(stamps[i] + deltas[pos[i]], &dts)
curr_reso = _reso_stamp(&dts)
if curr_reso < reso:
reso = curr_reso

return reso


# -----------------------------------------------------------------------
# period helpers


cdef ndarray[int64_t] localize_dt64arr_to_period(ndarray[int64_t] stamps,
int freq, object tz):
cdef:
Expand Down Expand Up @@ -1191,7 +1099,7 @@ class Period(_Period):

if freq is None:
try:
freq = frequencies.Resolution.get_freq(reso)
freq = Resolution.get_freq(reso)
except KeyError:
raise ValueError(
"Invalid frequency or could not infer: %s" % reso)
Expand Down Expand Up @@ -1236,7 +1144,7 @@ def _quarter_to_myear(year, quarter, freq):
if quarter <= 0 or quarter > 4:
raise ValueError('Quarter must be 1 <= q <= 4')

mnum = tslib._MONTH_NUMBERS[tslib._get_rule_month(freq)] + 1
mnum = _MONTH_NUMBERS[_get_rule_month(freq)] + 1
month = (mnum + (quarter - 1) * 3) % 12 + 1
if month > mnum:
year -= 1
Expand Down
55 changes: 1 addition & 54 deletions pandas/_libs/tslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ from datetime cimport (
# stdlib datetime imports
from datetime import time as datetime_time


from tslibs.np_datetime cimport (check_dts_bounds,
reverse_ops,
cmp_scalar,
Expand All @@ -61,12 +62,6 @@ from tslibs.np_datetime cimport (check_dts_bounds,
get_timedelta64_value)
from tslibs.np_datetime import OutOfBoundsDatetime

from khash cimport (
khiter_t,
kh_destroy_int64, kh_put_int64,
kh_init_int64, kh_int64_t,
kh_resize_int64, kh_get_int64)

from .tslibs.parsing import parse_datetime_string

cimport cython
Expand Down Expand Up @@ -868,33 +863,6 @@ Timestamp.min = Timestamp(_NS_LOWER_BOUND)
Timestamp.max = Timestamp(_NS_UPPER_BOUND)


# ----------------------------------------------------------------------
# Frequency inference

def unique_deltas(ndarray[int64_t] arr):
cdef:
Py_ssize_t i, n = len(arr)
int64_t val
khiter_t k
kh_int64_t *table
int ret = 0
list uniques = []

table = kh_init_int64()
kh_resize_int64(table, 10)
for i in range(n - 1):
val = arr[i + 1] - arr[i]
k = kh_get_int64(table, val)
if k == table.n_buckets:
kh_put_int64(table, val, &ret)
uniques.append(val)
kh_destroy_int64(table)

result = np.array(uniques, dtype=np.int64)
result.sort()
return result


cdef str _NDIM_STRING = "ndim"

# This is PITA. Because we inherit from datetime, which has very specific
Expand Down Expand Up @@ -1379,27 +1347,6 @@ _MONTH_NUMBERS = {k: i for i, k in enumerate(_MONTHS)}
_MONTH_ALIASES = {(k + 1): v for k, v in enumerate(_MONTHS)}


cpdef object _get_rule_month(object source, object default='DEC'):
"""
Return starting month of given freq, default is December.

Example
-------
>>> _get_rule_month('D')
'DEC'

>>> _get_rule_month('A-JAN')
'JAN'
"""
if hasattr(source, 'freqstr'):
source = source.freqstr
source = source.upper()
if '-' not in source:
return default
else:
return source.split('-')[1]


cpdef array_with_unit_to_datetime(ndarray values, unit, errors='coerce'):
"""
convert the ndarray according to the unit
Expand Down
Loading