summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release/1.14.0-notes.rst16
-rw-r--r--numpy/core/arrayprint.py53
-rw-r--r--numpy/core/src/multiarray/methods.c6
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src78
-rw-r--r--numpy/core/src/multiarray/strfuncs.c32
-rw-r--r--numpy/core/src/multiarray/strfuncs.h5
-rw-r--r--numpy/core/tests/test_arrayprint.py23
-rw-r--r--numpy/core/tests/test_nditer.py335
-rw-r--r--numpy/distutils/fcompiler/gnu.py14
-rw-r--r--numpy/lib/tests/test_twodim_base.py9
-rw-r--r--numpy/lib/twodim_base.py9
-rw-r--r--numpy/ma/core.py8
-rw-r--r--numpy/ma/tests/test_core.py10
-rw-r--r--numpy/matlib.py9
-rw-r--r--numpy/tests/test_matlib.py17
15 files changed, 428 insertions, 196 deletions
diff --git a/doc/release/1.14.0-notes.rst b/doc/release/1.14.0-notes.rst
index d5e42a423..3f1a6f7f6 100644
--- a/doc/release/1.14.0-notes.rst
+++ b/doc/release/1.14.0-notes.rst
@@ -403,6 +403,22 @@ elements uniquely.
Numpy complex-floating-scalars with values like ``inf*j`` or ``nan*j`` now
print as ``infj`` and ``nanj``, like the pure-python ``complex`` type.
+The ``FloatFormat`` and ``LongFloatFormat`` classes are deprecated and should
+both be replaced by ``FloatingFormat``. Similarly ``ComplexFormat`` and
+``LongComplexFormat`` should be replaced by ``ComplexFloatingFormat``.
+
+``void`` datatype elements are now printed in hex notation
+----------------------------------------------------------
+A hex representation compatible with the python ``bytes`` type is now printed
+for unstructured ``np.void`` elements (eg, ``V4`` datatype). Previously, in
+python2 the raw void data of the element was printed to stdout, or in python3
+the integer byte values were shown.
+
+printing style for ``void`` datatypes is now independently customizable
+-----------------------------------------------------------------------
+The printing style of ``np.void`` arrays is now independently customizable
+using the ``formatter`` argument to ``np.set_printoptions``, using the
+``'void'`` key, instead of the catch-all ``numpystr`` key as before.
Changes
=======
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index 14a11cff7..da173625e 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -291,6 +291,9 @@ def _object_format(o):
def repr_format(x):
return repr(x)
+def str_format(x):
+ return str(x)
+
def _get_formatdict(data, **opt):
prec, fmode = opt['precision'], opt['floatmode']
supp, sign = opt['suppress'], opt['sign']
@@ -302,11 +305,16 @@ def _get_formatdict(data, **opt):
'int': lambda: IntegerFormat(data),
'float': lambda:
FloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
+ 'longfloat': lambda:
+ FloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
'complexfloat': lambda:
ComplexFloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
+ 'longcomplexfloat': lambda:
+ ComplexFloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
'datetime': lambda: DatetimeFormat(data),
'timedelta': lambda: TimedeltaFormat(data),
'object': lambda: _object_format,
+ 'void': lambda: str_format,
'numpystr': lambda: repr_format,
'str': lambda: str}
@@ -325,7 +333,7 @@ def _get_formatdict(data, **opt):
for key in ['int']:
formatdict[key] = indirect(formatter['int_kind'])
if 'float_kind' in fkeys:
- for key in ['half', 'float', 'longfloat']:
+ for key in ['float', 'longfloat']:
formatdict[key] = indirect(formatter['float_kind'])
if 'complex_kind' in fkeys:
for key in ['complexfloat', 'longcomplexfloat']:
@@ -357,15 +365,23 @@ def _get_format_function(data, **options):
else:
return formatdict['int']()
elif issubclass(dtypeobj, _nt.floating):
- return formatdict['float']()
+ if issubclass(dtypeobj, _nt.longfloat):
+ return formatdict['longfloat']()
+ else:
+ return formatdict['float']()
elif issubclass(dtypeobj, _nt.complexfloating):
- return formatdict['complexfloat']()
+ if issubclass(dtypeobj, _nt.clongfloat):
+ return formatdict['longcomplexfloat']()
+ else:
+ return formatdict['complexfloat']()
elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)):
return formatdict['numpystr']()
elif issubclass(dtypeobj, _nt.datetime64):
return formatdict['datetime']()
elif issubclass(dtypeobj, _nt.object_):
return formatdict['object']()
+ elif issubclass(dtypeobj, _nt.void):
+ return formatdict['void']()
else:
return formatdict['numpystr']()
@@ -470,6 +486,7 @@ def array2string(a, max_line_width=None, precision=None,
- 'longfloat' : 128-bit floats
- 'complexfloat'
- 'longcomplexfloat' : composed of two 128-bit floats
+ - 'void' : type `numpy.void`
- 'numpystr' : types `numpy.string_` and `numpy.unicode_`
- 'str' : all other strings
@@ -798,6 +815,20 @@ class FloatingFormat(object):
pad_left=self.pad_left,
pad_right=self.pad_right)
+# for back-compatibility, we keep the classes for each float type too
+class FloatFormat(FloatingFormat):
+ def __init__(self, *args, **kwargs):
+ warnings.warn("FloatFormat has been replaced by FloatingFormat",
+ DeprecationWarning, stacklevel=2)
+ super(FloatFormat, self).__init__(*args, **kwargs)
+
+
+class LongFloatFormat(FloatingFormat):
+ def __init__(self, *args, **kwargs):
+ warnings.warn("LongFloatFormat has been replaced by FloatingFormat",
+ DeprecationWarning, stacklevel=2)
+ super(LongFloatFormat, self).__init__(*args, **kwargs)
+
def format_float_scientific(x, precision=None, unique=True, trim='k',
sign=False, pad_left=None, exp_digits=None):
@@ -989,6 +1020,22 @@ class ComplexFloatingFormat(object):
i = self.imag_format(x.imag)
return r + i + 'j'
+# for back-compatibility, we keep the classes for each complex type too
+class ComplexFormat(ComplexFloatingFormat):
+ def __init__(self, *args, **kwargs):
+ warnings.warn(
+ "ComplexFormat has been replaced by ComplexFloatingFormat",
+ DeprecationWarning, stacklevel=2)
+ super(ComplexFormat, self).__init__(*args, **kwargs)
+
+class LongComplexFormat(ComplexFloatingFormat):
+ def __init__(self, *args, **kwargs):
+ warnings.warn(
+ "LongComplexFormat has been replaced by ComplexFloatingFormat",
+ DeprecationWarning, stacklevel=2)
+ super(LongComplexFormat, self).__init__(*args, **kwargs)
+
+
class DatetimeFormat(object):
def __init__(self, x, unit=None, timezone=None, casting='same_kind'):
# Get the unit from the dtype
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 572352304..3f461b375 100644
--- a/numpy/core/src/multiarray/methods.c
+++ b/numpy/core/src/multiarray/methods.c
@@ -2505,6 +2505,12 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
(PyCFunction)array_ufunc,
METH_VARARGS | METH_KEYWORDS, NULL},
+#ifndef NPY_PY3K
+ {"__unicode__",
+ (PyCFunction)array_unicode,
+ METH_NOARGS, NULL},
+#endif
+
/* for the sys module */
{"__sizeof__",
(PyCFunction) array_sizeof,
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index 51c60ff9c..e032970f6 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -495,10 +495,61 @@ static PyObject *
}
/**end repeat**/
+
+/*
+ * Convert array of bytes to a string representation much like bytes.__repr__,
+ * but convert all bytes (including ASCII) to the `\x00` notation with
+ * uppercase hex codes (FF not ff).
+ *
+ * Largely copied from _Py_strhex_impl in CPython implementation
+ */
+static NPY_INLINE PyObject *
+_void_to_hex(const char* argbuf, const Py_ssize_t arglen,
+ const char *schars, const char *bprefix, const char *echars)
+{
+ PyObject *retval;
+ int extrachars, slen;
+ char *retbuf;
+ Py_ssize_t i, j;
+ char const *hexdigits = "0123456789ABCDEF";
+
+ extrachars = strlen(schars) + strlen(echars);
+ slen = extrachars + arglen*(2 + strlen(bprefix));
+
+ if (arglen > (PY_SSIZE_T_MAX / 2) - extrachars) {
+ return PyErr_NoMemory();
+ }
+
+ retbuf = (char *)PyMem_Malloc(slen);
+ if (!retbuf) {
+ return PyErr_NoMemory();
+ }
+
+ memcpy(retbuf, schars, strlen(schars));
+ j = strlen(schars);
+
+ for (i = 0; i < arglen; i++) {
+ unsigned char c;
+ memcpy(&retbuf[j], bprefix, strlen(bprefix));
+ j += strlen(bprefix);
+ c = (argbuf[i] >> 4) & 0xf;
+ retbuf[j++] = hexdigits[c];
+ c = argbuf[i] & 0xf;
+ retbuf[j++] = hexdigits[c];
+ }
+ memcpy(&retbuf[j], echars, strlen(echars));
+
+ retval = PyUString_FromStringAndSize(retbuf, slen);
+ PyMem_Free(retbuf);
+
+ return retval;
+}
+
static PyObject *
-voidtype_str(PyObject *self)
+voidtype_repr(PyObject *self)
{
- if (PyDataType_HASFIELDS(((PyVoidScalarObject*)self)->descr)) {
+ PyVoidScalarObject *s = (PyVoidScalarObject*) self;
+ if (PyDataType_HASFIELDS(s->descr)) {
static PyObject *reprfunc = NULL;
npy_cache_import("numpy.core.arrayprint",
@@ -509,18 +560,25 @@ voidtype_str(PyObject *self)
return PyObject_CallFunction(reprfunc, "O", self);
}
- else {
- PyObject *item, *item_str;
+ return _void_to_hex(s->obval, s->descr->elsize, "void(b'", "\\x", "')");
+}
+
+static PyObject *
+voidtype_str(PyObject *self)
+{
+ PyVoidScalarObject *s = (PyVoidScalarObject*) self;
+ if (PyDataType_HASFIELDS(s->descr)) {
+ static PyObject *reprfunc = NULL;
- item = gentype_generic_method(self, NULL, NULL, "item");
- if (item == NULL) {
+ npy_cache_import("numpy.core.arrayprint",
+ "_void_scalar_repr", &reprfunc);
+ if (reprfunc == NULL) {
return NULL;
}
- item_str = PyObject_Str(item);
- Py_DECREF(item);
- return item_str;
+ return PyObject_CallFunction(reprfunc, "O", self);
}
+ return _void_to_hex(s->obval, s->descr->elsize, "b'", "\\x", "'");
}
static PyObject *
@@ -4006,7 +4064,7 @@ initialize_numeric_types(void)
PyVoidArrType_Type.tp_getset = voidtype_getsets;
PyVoidArrType_Type.tp_as_mapping = &voidtype_as_mapping;
PyVoidArrType_Type.tp_as_sequence = &voidtype_as_sequence;
- PyVoidArrType_Type.tp_repr = voidtype_str;
+ PyVoidArrType_Type.tp_repr = voidtype_repr;
PyVoidArrType_Type.tp_str = voidtype_str;
PyIntegerArrType_Type.tp_getset = inttype_getsets;
diff --git a/numpy/core/src/multiarray/strfuncs.c b/numpy/core/src/multiarray/strfuncs.c
index bb94eb9f3..646d15cdb 100644
--- a/numpy/core/src/multiarray/strfuncs.c
+++ b/numpy/core/src/multiarray/strfuncs.c
@@ -225,3 +225,35 @@ array_format(PyArrayObject *self, PyObject *args)
);
}
}
+
+#ifndef NPY_PY3K
+
+NPY_NO_EXPORT PyObject *
+array_unicode(PyArrayObject *self)
+{
+ PyObject *uni;
+
+ if (PyArray_NDIM(self) == 0) {
+ PyObject *item = PyArray_ToScalar(PyArray_DATA(self), self);
+ if (item == NULL){
+ return NULL;
+ }
+
+ /* defer to invoking `unicode` on the scalar */
+ uni = PyObject_CallFunctionObjArgs(
+ (PyObject *)&PyUnicode_Type, item, NULL);
+ Py_DECREF(item);
+ }
+ else {
+ /* Do what unicode(self) would normally do */
+ PyObject *str = PyObject_Str((PyObject *)self);
+ if (str == NULL){
+ return NULL;
+ }
+ uni = PyUnicode_FromObject(str);
+ Py_DECREF(str);
+ }
+ return uni;
+}
+
+#endif
diff --git a/numpy/core/src/multiarray/strfuncs.h b/numpy/core/src/multiarray/strfuncs.h
index 5dd661a20..7e869d926 100644
--- a/numpy/core/src/multiarray/strfuncs.h
+++ b/numpy/core/src/multiarray/strfuncs.h
@@ -13,4 +13,9 @@ array_str(PyArrayObject *self);
NPY_NO_EXPORT PyObject *
array_format(PyArrayObject *self, PyObject *args);
+#ifndef NPY_PY3K
+ NPY_NO_EXPORT PyObject *
+ array_unicode(PyArrayObject *self);
+#endif
+
#endif
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
index 8123bee6f..62b5cf580 100644
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -157,6 +157,12 @@ class TestArray2String(object):
assert_(np.array2string(s, formatter={'numpystr':lambda s: s*2}) ==
'[abcabc defdef]')
+ # check for backcompat that using FloatFormat works and emits warning
+ with assert_warns(DeprecationWarning):
+ fmt = np.core.arrayprint.FloatFormat(x, 9, 'maxprec', False)
+ assert_equal(np.array2string(x, formatter={'float_kind': fmt}),
+ '[0. 1. 2.]')
+
def test_structure_format(self):
dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
x = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt)
@@ -186,6 +192,19 @@ class TestArray2String(object):
(1., 2.1234567890123456789, 3.), dtype=('f8,f8,f8'))
assert_equal(np.array2string(array_scalar), "(1., 2.12345679, 3.)")
+ def test_unstructured_void_repr(self):
+ a = np.array([27, 91, 50, 75, 7, 65, 10, 8,
+ 27, 91, 51, 49,109, 82,101,100], dtype='u1').view('V8')
+ assert_equal(repr(a[0]), r"void(b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08')")
+ assert_equal(str(a[0]), r"b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08'")
+ assert_equal(repr(a),
+ r"array([b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08'," "\n"
+ r" b'\x1B\x5B\x33\x31\x6D\x52\x65\x64']," "\n"
+ r" dtype='|V8')")
+
+ assert_equal(eval(repr(a), vars(np)), a)
+ assert_equal(eval(repr(a[0]), vars(np)), a[0])
+
class TestPrintOptions(object):
"""Test getting and setting global print options."""
@@ -241,8 +260,10 @@ class TestPrintOptions(object):
assert_equal(repr(x), "array([0., 1., 2.])")
def test_0d_arrays(self):
+ unicode = type(u'')
+ assert_equal(unicode(np.array(u'café', np.unicode_)), u'café')
+
if sys.version_info[0] >= 3:
- assert_equal(str(np.array('café', np.unicode_)), 'café')
assert_equal(repr(np.array('café', np.unicode_)),
"array('café',\n dtype='<U4')")
else:
diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py
index 59e11f22e..f3f8706b5 100644
--- a/numpy/core/tests/test_nditer.py
+++ b/numpy/core/tests/test_nditer.py
@@ -2146,172 +2146,197 @@ def test_iter_no_broadcast():
assert_raises(ValueError, nditer, [a, b, c], [],
[['readonly'], ['readonly'], ['readonly', 'no_broadcast']])
-def test_iter_nested_iters_basic():
- # Test nested iteration basic usage
- a = arange(12).reshape(2, 3, 2)
- i, j = np.nested_iters(a, [[0], [1, 2]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+class TestIterNested(object):
- i, j = np.nested_iters(a, [[0, 1], [2]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+ def test_basic(self):
+ # Test nested iteration basic usage
+ a = arange(12).reshape(2, 3, 2)
- i, j = np.nested_iters(a, [[0, 2], [1]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+ i, j = np.nested_iters(a, [[0], [1, 2]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
-def test_iter_nested_iters_reorder():
- # Test nested iteration basic usage
- a = arange(12).reshape(2, 3, 2)
+ i, j = np.nested_iters(a, [[0, 1], [2]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
- # In 'K' order (default), it gets reordered
- i, j = np.nested_iters(a, [[0], [2, 1]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+ i, j = np.nested_iters(a, [[0, 2], [1]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
- i, j = np.nested_iters(a, [[1, 0], [2]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+ def test_reorder(self):
+ # Test nested iteration basic usage
+ a = arange(12).reshape(2, 3, 2)
- i, j = np.nested_iters(a, [[2, 0], [1]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+ # In 'K' order (default), it gets reordered
+ i, j = np.nested_iters(a, [[0], [2, 1]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
- # In 'C' order, it doesn't
- i, j = np.nested_iters(a, [[0], [2, 1]], order='C')
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 2, 4, 1, 3, 5], [6, 8, 10, 7, 9, 11]])
+ i, j = np.nested_iters(a, [[1, 0], [2]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
- i, j = np.nested_iters(a, [[1, 0], [2]], order='C')
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1], [6, 7], [2, 3], [8, 9], [4, 5], [10, 11]])
+ i, j = np.nested_iters(a, [[2, 0], [1]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
- i, j = np.nested_iters(a, [[2, 0], [1]], order='C')
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 2, 4], [6, 8, 10], [1, 3, 5], [7, 9, 11]])
+ # In 'C' order, it doesn't
+ i, j = np.nested_iters(a, [[0], [2, 1]], order='C')
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 2, 4, 1, 3, 5], [6, 8, 10, 7, 9, 11]])
-def test_iter_nested_iters_flip_axes():
- # Test nested iteration with negative axes
- a = arange(12).reshape(2, 3, 2)[::-1, ::-1, ::-1]
+ i, j = np.nested_iters(a, [[1, 0], [2]], order='C')
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1], [6, 7], [2, 3], [8, 9], [4, 5], [10, 11]])
- # In 'K' order (default), the axes all get flipped
- i, j = np.nested_iters(a, [[0], [1, 2]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+ i, j = np.nested_iters(a, [[2, 0], [1]], order='C')
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 2, 4], [6, 8, 10], [1, 3, 5], [7, 9, 11]])
- i, j = np.nested_iters(a, [[0, 1], [2]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+ def test_flip_axes(self):
+ # Test nested iteration with negative axes
+ a = arange(12).reshape(2, 3, 2)[::-1, ::-1, ::-1]
- i, j = np.nested_iters(a, [[0, 2], [1]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+ # In 'K' order (default), the axes all get flipped
+ i, j = np.nested_iters(a, [[0], [1, 2]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
- # In 'C' order, flipping axes is disabled
- i, j = np.nested_iters(a, [[0], [1, 2]], order='C')
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[11, 10, 9, 8, 7, 6], [5, 4, 3, 2, 1, 0]])
+ i, j = np.nested_iters(a, [[0, 1], [2]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
- i, j = np.nested_iters(a, [[0, 1], [2]], order='C')
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[11, 10], [9, 8], [7, 6], [5, 4], [3, 2], [1, 0]])
+ i, j = np.nested_iters(a, [[0, 2], [1]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
- i, j = np.nested_iters(a, [[0, 2], [1]], order='C')
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[11, 9, 7], [10, 8, 6], [5, 3, 1], [4, 2, 0]])
+ # In 'C' order, flipping axes is disabled
+ i, j = np.nested_iters(a, [[0], [1, 2]], order='C')
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[11, 10, 9, 8, 7, 6], [5, 4, 3, 2, 1, 0]])
-def test_iter_nested_iters_broadcast():
- # Test nested iteration with broadcasting
- a = arange(2).reshape(2, 1)
- b = arange(3).reshape(1, 3)
+ i, j = np.nested_iters(a, [[0, 1], [2]], order='C')
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[11, 10], [9, 8], [7, 6], [5, 4], [3, 2], [1, 0]])
- i, j = np.nested_iters([a, b], [[0], [1]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]]])
+ i, j = np.nested_iters(a, [[0, 2], [1]], order='C')
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[11, 9, 7], [10, 8, 6], [5, 3, 1], [4, 2, 0]])
- i, j = np.nested_iters([a, b], [[1], [0]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[[0, 0], [1, 0]], [[0, 1], [1, 1]], [[0, 2], [1, 2]]])
+ def test_broadcast(self):
+ # Test nested iteration with broadcasting
+ a = arange(2).reshape(2, 1)
+ b = arange(3).reshape(1, 3)
-def test_iter_nested_iters_dtype_copy():
- # Test nested iteration with a copy to change dtype
+ i, j = np.nested_iters([a, b], [[0], [1]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]]])
+
+ i, j = np.nested_iters([a, b], [[1], [0]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[[0, 0], [1, 0]], [[0, 1], [1, 1]], [[0, 2], [1, 2]]])
+
+ def test_dtype_copy(self):
+ # Test nested iteration with a copy to change dtype
+
+ # copy
+ a = arange(6, dtype='i4').reshape(2, 3)
+ i, j = np.nested_iters(a, [[0], [1]],
+ op_flags=['readonly', 'copy'],
+ op_dtypes='f8')
+ assert_equal(j[0].dtype, np.dtype('f8'))
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1, 2], [3, 4, 5]])
+ vals = None
+
+ # updateifcopy
+ a = arange(6, dtype='f4').reshape(2, 3)
+ i, j = np.nested_iters(a, [[0], [1]],
+ op_flags=['readwrite', 'updateifcopy'],
+ casting='same_kind',
+ op_dtypes='f8')
+ assert_equal(j[0].dtype, np.dtype('f8'))
+ for x in i:
+ for y in j:
+ y[...] += 1
+ assert_equal(a, [[0, 1, 2], [3, 4, 5]])
+ i, j, x, y = (None,)*4 # force the updateifcopy
+ assert_equal(a, [[1, 2, 3], [4, 5, 6]])
+
+ def test_dtype_buffered(self):
+ # Test nested iteration with buffering to change dtype
+
+ a = arange(6, dtype='f4').reshape(2, 3)
+ i, j = np.nested_iters(a, [[0], [1]],
+ flags=['buffered'],
+ op_flags=['readwrite'],
+ casting='same_kind',
+ op_dtypes='f8')
+ assert_equal(j[0].dtype, np.dtype('f8'))
+ for x in i:
+ for y in j:
+ y[...] += 1
+ assert_equal(a, [[1, 2, 3], [4, 5, 6]])
+
+ def test_0d(self):
+ a = np.arange(12).reshape(2, 3, 2)
+ i, j = np.nested_iters(a, [[], [1, 0, 2]])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
+
+ i, j = np.nested_iters(a, [[1, 0, 2], []])
+ vals = []
+ for x in i:
+ vals.append([y for y in j])
+ assert_equal(vals, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]])
+
+ i, j, k = np.nested_iters(a, [[2, 0], [], [1]])
+ vals = []
+ for x in i:
+ for y in j:
+ vals.append([z for z in k])
+ assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
- # copy
- a = arange(6, dtype='i4').reshape(2, 3)
- i, j = np.nested_iters(a, [[0], [1]],
- op_flags=['readonly', 'copy'],
- op_dtypes='f8')
- assert_equal(j[0].dtype, np.dtype('f8'))
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1, 2], [3, 4, 5]])
- vals = None
-
- # updateifcopy
- a = arange(6, dtype='f4').reshape(2, 3)
- i, j = np.nested_iters(a, [[0], [1]],
- op_flags=['readwrite', 'updateifcopy'],
- casting='same_kind',
- op_dtypes='f8')
- assert_equal(j[0].dtype, np.dtype('f8'))
- for x in i:
- for y in j:
- y[...] += 1
- assert_equal(a, [[0, 1, 2], [3, 4, 5]])
- i, j, x, y = (None,)*4 # force the updateifcopy
- assert_equal(a, [[1, 2, 3], [4, 5, 6]])
-
-def test_iter_nested_iters_dtype_buffered():
- # Test nested iteration with buffering to change dtype
-
- a = arange(6, dtype='f4').reshape(2, 3)
- i, j = np.nested_iters(a, [[0], [1]],
- flags=['buffered'],
- op_flags=['readwrite'],
- casting='same_kind',
- op_dtypes='f8')
- assert_equal(j[0].dtype, np.dtype('f8'))
- for x in i:
- for y in j:
- y[...] += 1
- assert_equal(a, [[1, 2, 3], [4, 5, 6]])
def test_iter_reduction_error():
@@ -2639,28 +2664,6 @@ def test_0d_iter():
assert_equal(vals['d'], 0.5)
-def test_0d_nested_iter():
- a = np.arange(12).reshape(2, 3, 2)
- i, j = np.nested_iters(a, [[], [1, 0, 2]])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
-
- i, j = np.nested_iters(a, [[1, 0, 2], []])
- vals = []
- for x in i:
- vals.append([y for y in j])
- assert_equal(vals, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]])
-
- i, j, k = np.nested_iters(a, [[2, 0], [], [1]])
- vals = []
- for x in i:
- for y in j:
- vals.append([z for z in k])
- assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
-
-
def test_iter_too_large():
# The total size of the iterator must not exceed the maximum intp due
# to broadcasting. Dividing by 1024 will keep it small enough to
diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py
index 04e846e23..0ebbe79dc 100644
--- a/numpy/distutils/fcompiler/gnu.py
+++ b/numpy/distutils/fcompiler/gnu.py
@@ -200,10 +200,9 @@ class GnuFCompiler(FCompiler):
opt.append(d2)
opt.append(d)
# For Macports / Linux, libgfortran and libgcc are not co-located
- if sys.platform[:5] == 'linux' or sys.platform == 'darwin':
- lib_gfortran_dir = self.get_libgfortran_dir()
- if lib_gfortran_dir:
- opt.append(lib_gfortran_dir)
+ lib_gfortran_dir = self.get_libgfortran_dir()
+ if lib_gfortran_dir:
+ opt.append(lib_gfortran_dir)
return opt
def get_libraries(self):
@@ -350,10 +349,9 @@ class Gnu95FCompiler(GnuFCompiler):
if os.path.exists(os.path.join(mingwdir, "libmingwex.a")):
opt.append(mingwdir)
# For Macports / Linux, libgfortran and libgcc are not co-located
- if sys.platform[:5] == 'linux' or sys.platform == 'darwin':
- lib_gfortran_dir = self.get_libgfortran_dir()
- if lib_gfortran_dir:
- opt.append(lib_gfortran_dir)
+ lib_gfortran_dir = self.get_libgfortran_dir()
+ if lib_gfortran_dir:
+ opt.append(lib_gfortran_dir)
return opt
def get_libraries(self):
diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py
index 6bf668dee..8183f7ca6 100644
--- a/numpy/lib/tests/test_twodim_base.py
+++ b/numpy/lib/tests/test_twodim_base.py
@@ -95,6 +95,15 @@ class TestEye(object):
def test_bool(self):
assert_equal(eye(2, 2, dtype=bool), [[True, False], [False, True]])
+ def test_order(self):
+ mat_c = eye(4, 3, k=-1)
+ mat_f = eye(4, 3, k=-1, order='F')
+ assert_equal(mat_c, mat_f)
+ assert mat_c.flags.c_contiguous
+ assert not mat_c.flags.f_contiguous
+ assert not mat_f.flags.c_contiguous
+ assert mat_f.flags.f_contiguous
+
class TestDiag(object):
def test_vector(self):
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index a6259219a..402c18850 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -137,7 +137,7 @@ def flipud(m):
return m[::-1, ...]
-def eye(N, M=None, k=0, dtype=float):
+def eye(N, M=None, k=0, dtype=float, order='C'):
"""
Return a 2-D array with ones on the diagonal and zeros elsewhere.
@@ -153,6 +153,11 @@ def eye(N, M=None, k=0, dtype=float):
to a lower diagonal.
dtype : data-type, optional
Data-type of the returned array.
+ order : {'C', 'F'}, optional
+ Whether the output should be stored in row-major (C-style) or
+ column-major (Fortran-style) order in memory.
+
+ .. versionadded:: 1.14.0
Returns
-------
@@ -178,7 +183,7 @@ def eye(N, M=None, k=0, dtype=float):
"""
if M is None:
M = N
- m = zeros((N, M), dtype=dtype)
+ m = zeros((N, M), dtype=dtype, order=order)
if k >= M:
return m
if k >= 0:
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index b71e8fa06..0d02bb315 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -3867,6 +3867,10 @@ class MaskedArray(ndarray):
def __str__(self):
return str(self._insert_masked_print())
+ if sys.version_info.major < 3:
+ def __unicode__(self):
+ return unicode(self._insert_masked_print())
+
def __repr__(self):
"""
Literal string representation.
@@ -6238,6 +6242,10 @@ class MaskedConstant(MaskedArray):
def __str__(self):
return str(masked_print_option._display)
+ if sys.version_info.major < 3:
+ def __unicode__(self):
+ return unicode(masked_print_option._display)
+
def __repr__(self):
if self is MaskedConstant.__singleton:
return 'masked'
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index fd8d629f9..03de71f81 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -500,6 +500,16 @@ class TestMaskedArray(object):
' fill_value = 999999)\n'
)
+ def test_0d_unicode(self):
+ u = u'caf\xe9'
+ utype = type(u)
+
+ arr_nomask = np.ma.array(u)
+ arr_masked = np.ma.array(u, mask=True)
+
+ assert_equal(utype(arr_nomask), u)
+ assert_equal(utype(arr_masked), u'--')
+
def test_pickling(self):
# Tests pickling
for dtype in (int, float, str, object):
diff --git a/numpy/matlib.py b/numpy/matlib.py
index 656ca3458..004e5f0c8 100644
--- a/numpy/matlib.py
+++ b/numpy/matlib.py
@@ -173,7 +173,7 @@ def identity(n,dtype=None):
b.flat = a
return b
-def eye(n,M=None, k=0, dtype=float):
+def eye(n,M=None, k=0, dtype=float, order='C'):
"""
Return a matrix with ones on the diagonal and zeros elsewhere.
@@ -189,6 +189,11 @@ def eye(n,M=None, k=0, dtype=float):
and a negative value to a lower diagonal.
dtype : dtype, optional
Data-type of the returned matrix.
+ order : {'C', 'F'}, optional
+ Whether the output should be stored in row-major (C-style) or
+ column-major (Fortran-style) order in memory.
+
+ .. versionadded:: 1.14.0
Returns
-------
@@ -210,7 +215,7 @@ def eye(n,M=None, k=0, dtype=float):
[ 0., 0., 0.]])
"""
- return asmatrix(np.eye(n, M, k, dtype))
+ return asmatrix(np.eye(n, M=M, k=k, dtype=dtype, order=order))
def rand(*args):
"""
diff --git a/numpy/tests/test_matlib.py b/numpy/tests/test_matlib.py
index 11227b19a..d16975934 100644
--- a/numpy/tests/test_matlib.py
+++ b/numpy/tests/test_matlib.py
@@ -28,10 +28,19 @@ def test_identity():
assert_array_equal(x, np.matrix([[1, 0], [0, 1]]))
def test_eye():
- x = numpy.matlib.eye(3, k=1, dtype=int)
- assert_array_equal(x, np.matrix([[ 0, 1, 0],
- [ 0, 0, 1],
- [ 0, 0, 0]]))
+ xc = numpy.matlib.eye(3, k=1, dtype=int)
+ assert_array_equal(xc, np.matrix([[ 0, 1, 0],
+ [ 0, 0, 1],
+ [ 0, 0, 0]]))
+ assert xc.flags.c_contiguous
+ assert not xc.flags.f_contiguous
+
+ xf = numpy.matlib.eye(3, 4, dtype=int, order='F')
+ assert_array_equal(xf, np.matrix([[ 1, 0, 0, 0],
+ [ 0, 1, 0, 0],
+ [ 0, 0, 1, 0]]))
+ assert not xf.flags.c_contiguous
+ assert xf.flags.f_contiguous
def test_rand():
x = numpy.matlib.rand(3)