/usr/lib/python2.7/dist-packages/numba/npdatetime.py is in python-numba 0.34.0-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | """
Helper functions for np.timedelta64 and np.datetime64.
For now, multiples-of-units (for example timedeltas expressed in tens
of seconds) are not supported.
"""
import numpy as np
DATETIME_UNITS = {
'Y': 0, # Years
'M': 1, # Months
'W': 2, # Weeks
# Yes, there's a gap here
'D': 4, # Days
'h': 5, # Hours
'm': 6, # Minutes
's': 7, # Seconds
'ms': 8, # Milliseconds
'us': 9, # Microseconds
'ns': 10, # Nanoseconds
'ps': 11, # Picoseconds
'fs': 12, # Femtoseconds
'as': 13, # Attoseconds
'': 14, # "generic", i.e. unit-less
}
NAT = np.timedelta64('nat').astype(np.int64)
# NOTE: numpy has several inconsistent functions for timedelta casting:
# - can_cast_timedelta64_{metadata,units}() disallows "safe" casting
# to and from generic units
# - cast_timedelta_to_timedelta() allows casting from (but not to)
# generic units
# - compute_datetime_metadata_greatest_common_divisor() allows casting from
# generic units (used for promotion)
def same_kind(src, dest):
"""
Whether the *src* and *dest* units are of the same kind.
"""
return (DATETIME_UNITS[src] < 5) == (DATETIME_UNITS[dest] < 5)
def can_cast_timedelta_units(src, dest):
# Mimick numpy's "safe" casting and promotion
# `dest` must be more precise than `src` and they must be compatible
# for conversion.
# XXX should we switch to enforcing "same-kind" for Numpy 1.10+ ?
src = DATETIME_UNITS[src]
dest = DATETIME_UNITS[dest]
if src == dest:
return True
if src == 14:
return True
if src > dest:
return False
if dest == 14:
# unit-less timedelta64 is not compatible with anything else
return False
if src <= 1 and dest > 1:
# Cannot convert between months or years and other units
return False
return True
# Exact conversion factors from one unit to the immediately more precise one
_factors = {
0: (1, 12), # Years -> Months
2: (4, 7), # Weeks -> Days
4: (5, 24), # Days -> Hours
5: (6, 60), # Hours -> Minutes
6: (7, 60), # Minutes -> Seconds
7: (8, 1000),
8: (9, 1000),
9: (10, 1000),
10: (11, 1000),
11: (12, 1000),
12: (13, 1000),
}
def _get_conversion_multiplier(big_unit_code, small_unit_code):
"""
Return an integer multiplier allowing to convert from *big_unit_code*
to *small_unit_code*.
None is returned if the conversion is not possible through a
simple integer multiplication.
"""
# Mimicks get_datetime_units_factor() in numpy's datetime.c,
# with a twist to allow no-op conversion from generic units.
if big_unit_code == 14:
return 1
c = big_unit_code
factor = 1
while c < small_unit_code:
try:
c, mult = _factors[c]
except KeyError:
# No possible conversion
return None
factor *= mult
if c == small_unit_code:
return factor
else:
return None
def get_timedelta_conversion_factor(src_unit, dest_unit):
"""
Return an integer multiplier allowing to convert from timedeltas
of *src_unit* to *dest_unit*.
"""
return _get_conversion_multiplier(DATETIME_UNITS[src_unit],
DATETIME_UNITS[dest_unit])
def get_datetime_timedelta_conversion(datetime_unit, timedelta_unit):
"""
Compute a possible conversion for combining *datetime_unit* and
*timedelta_unit* (presumably for adding or subtracting).
Return (result unit, integer datetime multiplier, integer timedelta multiplier).
RuntimeError is raised if the combination is impossible.
"""
# XXX now unused (I don't know where / how Numpy uses this)
dt_unit_code = DATETIME_UNITS[datetime_unit]
td_unit_code = DATETIME_UNITS[timedelta_unit]
if td_unit_code == 14 or dt_unit_code == 14:
return datetime_unit, 1, 1
if td_unit_code < 2 and dt_unit_code >= 2:
# Cannot combine Y or M timedelta64 with a finer-grained datetime64
raise RuntimeError("cannot combine datetime64(%r) and timedelta64(%r)"
% (datetime_unit, timedelta_unit))
dt_factor, td_factor = 1, 1
# If years or months, the datetime unit is first scaled to weeks or days,
# then conversion continues below. This is the same algorithm as used
# in Numpy's get_datetime_conversion_factor() (src/multiarray/datetime.c):
# """Conversions between years/months and other units use
# the factor averaged over the 400 year leap year cycle."""
if dt_unit_code == 0:
if td_unit_code >= 4:
dt_factor = 97 + 400 * 365
td_factor = 400
dt_unit_code = 4
elif td_unit_code == 2:
dt_factor = 97 + 400 * 365
td_factor = 400 * 7
dt_unit_code = 2
elif dt_unit_code == 1:
if td_unit_code >= 4:
dt_factor = 97 + 400 * 365
td_factor = 400 * 12
dt_unit_code = 4
elif td_unit_code == 2:
dt_factor = 97 + 400 * 365
td_factor = 400 * 12 * 7
dt_unit_code = 2
if td_unit_code >= dt_unit_code:
factor = _get_conversion_multiplier(dt_unit_code, td_unit_code)
assert factor is not None, (dt_unit_code, td_unit_code)
return timedelta_unit, dt_factor * factor, td_factor
else:
factor = _get_conversion_multiplier(td_unit_code, dt_unit_code)
assert factor is not None, (dt_unit_code, td_unit_code)
return datetime_unit, dt_factor, td_factor * factor
def combine_datetime_timedelta_units(datetime_unit, timedelta_unit):
"""
Return the unit result of combining *datetime_unit* with *timedelta_unit*
(e.g. by adding or subtracting). None is returned if combining
those units is forbidden.
"""
dt_unit_code = DATETIME_UNITS[datetime_unit]
td_unit_code = DATETIME_UNITS[timedelta_unit]
if dt_unit_code == 14:
return timedelta_unit
elif td_unit_code == 14:
return datetime_unit
if td_unit_code < 2 and dt_unit_code >= 2:
return None
if dt_unit_code > td_unit_code:
return datetime_unit
else:
return timedelta_unit
def get_best_unit(unit_a, unit_b):
"""
Get the best (i.e. finer-grained) of two units.
"""
a = DATETIME_UNITS[unit_a]
b = DATETIME_UNITS[unit_b]
if a == 14:
return unit_b
if b == 14:
return unit_a
if b > a:
return unit_b
return unit_a
|