summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wiebe <mwiebe@enthought.com>2011-06-03 12:20:52 -0500
committerMark Wiebe <mwiebe@enthought.com>2011-06-03 12:20:52 -0500
commitde719936cf64df1a8f1096fb7f3a2be720906da4 (patch)
treed0106c1e1e4e5a7483747c36fbc0e00314153573
parent681adf030eda8e9097cf53856dda6426b2351485 (diff)
downloadnumpy-de719936cf64df1a8f1096fb7f3a2be720906da4.tar.gz
ENH: datetime: Remove TimeInteger, partially fix up datetime array printing
The TimeInteger seemed like the wrong abstraction to me. Timedelta is reasonable as an integer, and in fact if NumPy supported arbitrary unit metadata, Timedelta could be removed and that mechanism used instead. Datetime, however, doesn't represent an integer. Datetime has no zero (barring big bang, God's creation, or some other choice...), something which integers definitely have.
-rw-r--r--numpy/core/arrayprint.py44
-rw-r--r--numpy/core/numeric.py2
-rw-r--r--numpy/core/numerictypes.py5
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src1
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c7
-rw-r--r--numpy/core/src/multiarray/scalarapi.c10
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src9
-rw-r--r--numpy/core/tests/test_arrayprint.py2
-rw-r--r--numpy/core/tests/test_regression.py2
9 files changed, 56 insertions, 26 deletions
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index d0b899901..c02d3e0a1 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -72,7 +72,8 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
- 'bool'
- 'int'
- - 'timeint' : a `numpy.timeinteger`
+ - 'timedelta' : a `numpy.timedelta64`
+ - 'datetime' : a `numpy.datetime64`
- 'float'
- 'longfloat' : 128-bit floats
- 'complexfloat'
@@ -83,7 +84,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
Other keys that can be used to set a group of types at once are::
- 'all' : sets all types
- - 'int_kind' : sets 'int' and 'timeint'
+ - 'int_kind' : sets 'int'
- 'float_kind' : sets 'float' and 'longfloat'
- 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
- 'str_kind' : sets 'str' and 'numpystr'
@@ -239,12 +240,13 @@ def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
formatdict = {'bool' : _boolFormatter,
'int' : IntegerFormat(data),
- 'timeint' : str,
'float' : FloatFormat(data, precision, suppress_small),
'longfloat' : LongFloatFormat(precision),
'complexfloat' : ComplexFormat(data, precision,
suppress_small),
'longcomplexfloat' : LongComplexFormat(precision),
+ 'datetime' : DatetimeFormat(True, None),
+ 'timedelta' : TimedeltaFormat(data),
'numpystr' : repr,
'str' : str}
if formatter is not None:
@@ -253,7 +255,7 @@ def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
for key in formatdict.keys():
formatdict[key] = formatter['all']
if 'int_kind' in fkeys:
- for key in ['int', 'timeint']:
+ for key in ['int']:
formatdict[key] = formatter['int_kind']
if 'float_kind' in fkeys:
for key in ['float', 'longfloat']:
@@ -280,8 +282,8 @@ def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
if issubclass(dtypeobj, _nt.bool_):
format_function = formatdict['bool']
elif issubclass(dtypeobj, _nt.integer):
- if issubclass(dtypeobj, _nt.timeinteger):
- format_function = formatdict['timeint']
+ if issubclass(dtypeobj, _nt.timedelta64):
+ format_function = formatdict['timedelta']
else:
format_function = formatdict['int']
elif issubclass(dtypeobj, _nt.floating):
@@ -296,6 +298,8 @@ def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
format_function = formatdict['complexfloat']
elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)):
format_function = formatdict['numpystr']
+ elif issubclass(dtypeobj, _nt.datetime64):
+ format_function = formatdict['datetime']
else:
format_function = formatdict['str']
@@ -361,7 +365,8 @@ def array2string(a, max_line_width=None, precision=None,
- 'bool'
- 'int'
- - 'timeint' : a `numpy.timeinteger`
+ - 'timedelta' : a `numpy.timedelta64`
+ - 'datetime' : a `numpy.datetime64`
- 'float'
- 'longfloat' : 128-bit floats
- 'complexfloat'
@@ -372,7 +377,7 @@ def array2string(a, max_line_width=None, precision=None,
Other keys that can be used to set a group of types at once are::
- 'all' : sets all types
- - 'int_kind' : sets 'int' and 'timeint'
+ - 'int_kind' : sets 'int'
- 'float_kind' : sets 'float' and 'longfloat'
- 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
- 'str_kind' : sets 'str' and 'numpystr'
@@ -691,3 +696,26 @@ class ComplexFormat(object):
else:
i = i + 'j'
return r + i
+
+class DatetimeFormat(object):
+ def __init__(self, uselocaltime=True, overrideunit=None):
+ self.local = uselocaltime
+ self.unit = overrideunit
+
+ def __call__(self, x):
+ return "'%s'" % str(x)
+
+class TimedeltaFormat(object):
+ def __init__(self, data):
+ if data.dtype.kind == 'm':
+ v = data.view('i8')
+ max_str_len = max(len(str(maximum.reduce(v))),
+ len(str(minimum.reduce(v))))
+ self.format = '%' + str(max_str_len) + 'd'
+
+ def __call__(self, x):
+ if _MININT < x < _MAXINT:
+ return self.format % x.astype('i8')
+ else:
+ return "%s" % x
+
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index 55ab74168..67235e4d1 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -1332,7 +1332,7 @@ def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):
if typeless and arr.size:
return cName + "(%s)" % lst
else:
- typename=arr.dtype.name
+ typename="'%s'" % arr.dtype.name
lf = ''
if issubclass(arr.dtype.type, flexible):
if arr.dtype.names:
diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py
index 5ab874ccb..7afdf2263 100644
--- a/numpy/core/numerictypes.py
+++ b/numpy/core/numerictypes.py
@@ -39,8 +39,9 @@ Exported symbols include:
longfloat, clongfloat,
- datetime_, timedelta_, (these inherit from timeinteger which inherits
- from signedinteger)
+ datetime_
+ timedelta_, (this inherits from from signedinteger, as it is
+ a signed integer with an associated time unit)
As part of the type-hierarchy: xx -- is bit-width
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index 426a9be91..e55c7c133 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -3767,7 +3767,6 @@ set_typeinfo(PyObject *dict)
SETTYPE(Integer);
SETTYPE(Inexact);
SETTYPE(SignedInteger);
- SETTYPE(TimeInteger);
SETTYPE(UnsignedInteger);
SETTYPE(Floating);
SETTYPE(ComplexFloating);
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index 6a1cc5e9d..054bdb6c1 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -3574,9 +3574,10 @@ setup_scalartypes(PyObject *NPY_UNUSED(dict))
SINGLE_INHERIT(LongLong, SignedInteger);
#endif
- SINGLE_INHERIT(TimeInteger, SignedInteger);
- SINGLE_INHERIT(Datetime, TimeInteger);
- SINGLE_INHERIT(Timedelta, TimeInteger);
+ /* Datetime doesn't fit in any category */
+ SINGLE_INHERIT(Datetime, Generic);
+ /* Timedelta is an integer with an associated unit */
+ SINGLE_INHERIT(Timedelta, SignedInteger);
/*
fprintf(stderr,
diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c
index 3d2fae39c..d4ccc42c8 100644
--- a/numpy/core/src/multiarray/scalarapi.c
+++ b/numpy/core/src/multiarray/scalarapi.c
@@ -94,10 +94,7 @@ scalar_value(PyObject *scalar, PyArray_Descr *descr)
_IFCASE(Int);
_IFCASE(Long);
_IFCASE(LongLong);
- if _CHK(TimeInteger) {
- _IFCASE(Datetime);
- _IFCASE(Timedelta);
- }
+ _IFCASE(Timedelta);
}
else {
/* Unsigned Integer */
@@ -127,6 +124,9 @@ scalar_value(PyObject *scalar, PyArray_Descr *descr)
else if (_CHK(Bool)) {
return _OBJ(Bool);
}
+ else if (_CHK(Datetime)) {
+ return _OBJ(Datetime);
+ }
else if (_CHK(Flexible)) {
if (_CHK(String)) {
return (void *)PyString_AS_STRING(scalar);
@@ -522,7 +522,7 @@ PyArray_DescrFromScalar(PyObject *sc)
return descr;
}
- if (PyArray_IsScalar(sc, TimeInteger)) {
+ if (PyArray_IsScalar(sc, Datetime) || PyArray_IsScalar(sc, Timedelta)) {
PyObject *cobj;
PyArray_DatetimeMetaData *dt_data;
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index 4203ca37b..03b3c8c86 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -28,6 +28,9 @@ NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[] = {
{PyObject_HEAD_INIT(&PyBoolArrType_Type) 1},
};
+/* TimeInteger is deleted, but still here to fill the API slot */
+NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type;
+
/*
* Inheritance is established later when tp_bases is set (or tp_base for
* single inheritance)
@@ -35,9 +38,9 @@ NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[] = {
/**begin repeat
* #name = number, integer, signedinteger, unsignedinteger, inexact,
- * floating, complexfloating, flexible, character, timeinteger#
+ * floating, complexfloating, flexible, character#
* #NAME = Number, Integer, SignedInteger, UnsignedInteger, Inexact,
- * Floating, ComplexFloating, Flexible, Character, TimeInteger#
+ * Floating, ComplexFloating, Flexible, Character#
*/
NPY_NO_EXPORT PyTypeObject Py@NAME@ArrType_Type = {
#if defined(NPY_PY3K)
@@ -3945,7 +3948,7 @@ initialize_numeric_types(void)
/**begin repeat
* #NAME= Number, Integer, SignedInteger, UnsignedInteger, Inexact,
- * Floating, ComplexFloating, Flexible, Character, TimeInteger#
+ * Floating, ComplexFloating, Flexible, Character#
*/
Py@NAME@ArrType_Type.tp_flags = BASEFLAGS;
/**end repeat**/
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
index dd86fcbd9..b1dbb1d68 100644
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -80,8 +80,6 @@ class TestArray2String(TestCase):
"[. o O]")
assert_(np.array2string(x, formatter={'int_kind':_format_function}) ==\
"[. o O]")
- assert_(np.array2string(x, formatter={'timeint':_format_function}) == \
- "[0 1 2]")
assert_(np.array2string(x, formatter={'all':lambda x: "%.4f" % x}) == \
"[0.0000 1.0000 2.0000]")
assert_(np.array2string(x, formatter={'int':lambda x: hex(x)}) == \
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 5264ff31e..ad043ea8a 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -1317,7 +1317,7 @@ class TestRegression(TestCase):
def test_ticket_1539(self):
dtypes = [x for x in np.typeDict.values()
if (issubclass(x, np.number)
- and not issubclass(x, np.timeinteger))]
+ and not issubclass(x, np.timedelta_))]
a = np.array([], dtypes[0])
failures = []
for x in dtypes: