summaryrefslogtreecommitdiff
path: root/numpy/core/numeric.py
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2018-07-31 00:41:28 -0700
committerGitHub <noreply@github.com>2018-07-31 00:41:28 -0700
commit7f4579279a6a6aa07df664b901afa36ab3fc5ce0 (patch)
tree3524c05c661f4948eabf066b46b5ad3aaf6ad617 /numpy/core/numeric.py
parent24960daf3e326591047eb099af840da6e95d0910 (diff)
parent9bb569c4e0e1cf08128179d157bdab10c8706a97 (diff)
downloadnumpy-7f4579279a6a6aa07df664b901afa36ab3fc5ce0.tar.gz
Merge branch 'master' into ix_-preserve-type
Diffstat (limited to 'numpy/core/numeric.py')
-rw-r--r--numpy/core/numeric.py731
1 files changed, 279 insertions, 452 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index b90b0a9c9..e5570791a 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -1,10 +1,16 @@
from __future__ import division, absolute_import, print_function
-import collections
+try:
+ # Accessing collections abstract classes from collections
+ # has been deprecated since Python 3.3
+ import collections.abc as collections_abc
+except ImportError:
+ import collections as collections_abc
import itertools
import operator
import sys
import warnings
+import numbers
import numpy as np
from . import multiarray
@@ -17,17 +23,17 @@ from .multiarray import (
inner, int_asbuffer, lexsort, matmul, may_share_memory,
min_scalar_type, ndarray, nditer, nested_iters, promote_types,
putmask, result_type, set_numeric_ops, shares_memory, vdot, where,
- zeros)
+ zeros, normalize_axis_index)
if sys.version_info[0] < 3:
from .multiarray import newbuffer, getbuffer
from . import umath
-from .umath import (invert, sin, UFUNC_BUFSIZE_DEFAULT, ERR_IGNORE,
- ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT, ERR_LOG,
- ERR_DEFAULT, PINF, NAN)
+from .umath import (multiply, invert, sin, UFUNC_BUFSIZE_DEFAULT,
+ ERR_IGNORE, ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT,
+ ERR_LOG, ERR_DEFAULT, PINF, NAN)
from . import numerictypes
from .numerictypes import longlong, intc, int_, float_, complex_, bool_
-from ._internal import TooHardError
+from ._internal import TooHardError, AxisError
bitwise_not = invert
ufunc = type(sin)
@@ -41,33 +47,34 @@ else:
import cPickle as pickle
import __builtin__ as builtins
-loads = pickle.loads
+
+def loads(*args, **kwargs):
+ # NumPy 1.15.0, 2017-12-10
+ warnings.warn(
+ "np.core.numeric.loads is deprecated, use pickle.loads instead",
+ DeprecationWarning, stacklevel=2)
+ return pickle.loads(*args, **kwargs)
__all__ = [
'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc',
- 'arange', 'array', 'zeros', 'count_nonzero', 'empty', 'broadcast',
- 'dtype', 'fromstring', 'fromfile', 'frombuffer', 'int_asbuffer',
- 'where', 'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose',
- 'lexsort', 'set_numeric_ops', 'can_cast', 'promote_types',
- 'min_scalar_type', 'result_type', 'asarray', 'asanyarray',
- 'ascontiguousarray', 'asfortranarray', 'isfortran', 'empty_like',
- 'zeros_like', 'ones_like', 'correlate', 'convolve', 'inner', 'dot',
- 'outer', 'vdot', 'alterdot', 'restoredot', 'roll',
- 'rollaxis', 'moveaxis', 'cross', 'tensordot', 'array2string',
- 'get_printoptions', 'set_printoptions', 'array_repr', 'array_str',
- 'set_string_function', 'little_endian', 'require', 'fromiter',
- 'array_equal', 'array_equiv', 'indices', 'fromfunction', 'isclose', 'load',
- 'loads', 'isscalar', 'binary_repr', 'base_repr', 'ones', 'identity',
- 'allclose', 'compare_chararrays', 'putmask', 'seterr', 'geterr',
- 'setbufsize', 'getbufsize', 'seterrcall', 'geterrcall', 'errstate',
- 'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_',
- 'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS', 'BUFSIZE',
- 'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like', 'matmul',
- 'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS', 'MAY_SHARE_EXACT',
- 'TooHardError',
- ]
-
+ 'arange', 'array', 'zeros', 'count_nonzero', 'empty', 'broadcast', 'dtype',
+ 'fromstring', 'fromfile', 'frombuffer', 'int_asbuffer', 'where',
+ 'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose', 'lexsort',
+ 'set_numeric_ops', 'can_cast', 'promote_types', 'min_scalar_type',
+ 'result_type', 'asarray', 'asanyarray', 'ascontiguousarray',
+ 'asfortranarray', 'isfortran', 'empty_like', 'zeros_like', 'ones_like',
+ 'correlate', 'convolve', 'inner', 'dot', 'outer', 'vdot', 'roll',
+ 'rollaxis', 'moveaxis', 'cross', 'tensordot', 'little_endian', 'require',
+ 'fromiter', 'array_equal', 'array_equiv', 'indices', 'fromfunction',
+ 'isclose', 'load', 'loads', 'isscalar', 'binary_repr', 'base_repr', 'ones',
+ 'identity', 'allclose', 'compare_chararrays', 'putmask', 'seterr',
+ 'geterr', 'setbufsize', 'getbufsize', 'seterrcall', 'geterrcall',
+ 'errstate', 'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN',
+ 'False_', 'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS',
+ 'BUFSIZE', 'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like',
+ 'matmul', 'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS',
+ 'MAY_SHARE_EXACT', 'TooHardError', 'AxisError']
if sys.version_info[0] < 3:
__all__.extend(['getbuffer', 'newbuffer'])
@@ -116,11 +123,10 @@ def zeros_like(a, dtype=None, order='K', subok=True):
See Also
--------
- ones_like : Return an array of ones with shape and type of input.
empty_like : Return an empty array with shape and type of input.
+ ones_like : Return an array of ones with shape and type of input.
+ full_like : Return a new array with shape of input filled with value.
zeros : Return a new array setting values to zero.
- ones : Return a new array setting values to one.
- empty : Return a new uninitialized array.
Examples
--------
@@ -133,7 +139,7 @@ def zeros_like(a, dtype=None, order='K', subok=True):
array([[0, 0, 0],
[0, 0, 0]])
- >>> y = np.arange(3, dtype=np.float)
+ >>> y = np.arange(3, dtype=float)
>>> y
array([ 0., 1., 2.])
>>> np.zeros_like(y)
@@ -158,9 +164,10 @@ def ones(shape, dtype=None, order='C'):
dtype : data-type, optional
The desired data-type for the array, e.g., `numpy.int8`. Default is
`numpy.float64`.
- order : {'C', 'F'}, optional
- Whether to store multidimensional data in C- or Fortran-contiguous
- (row- or column-wise) order in memory.
+ order : {'C', 'F'}, optional, default: C
+ Whether to store multi-dimensional data in row-major
+ (C-style) or column-major (Fortran-style) order in
+ memory.
Returns
-------
@@ -169,14 +176,18 @@ def ones(shape, dtype=None, order='C'):
See Also
--------
- zeros, ones_like
+ ones_like : Return an array of ones with shape and type of input.
+ empty : Return a new uninitialized array.
+ zeros : Return a new array setting values to zero.
+ full : Return a new array of given shape filled with value.
+
Examples
--------
>>> np.ones(5)
array([ 1., 1., 1., 1., 1.])
- >>> np.ones((5,), dtype=np.int)
+ >>> np.ones((5,), dtype=int)
array([1, 1, 1, 1, 1])
>>> np.ones((2, 1))
@@ -226,11 +237,10 @@ def ones_like(a, dtype=None, order='K', subok=True):
See Also
--------
- zeros_like : Return an array of zeros with shape and type of input.
empty_like : Return an empty array with shape and type of input.
- zeros : Return a new array setting values to zero.
+ zeros_like : Return an array of zeros with shape and type of input.
+ full_like : Return a new array with shape of input filled with value.
ones : Return a new array setting values to one.
- empty : Return a new uninitialized array.
Examples
--------
@@ -243,7 +253,7 @@ def ones_like(a, dtype=None, order='K', subok=True):
array([[1, 1, 1],
[1, 1, 1]])
- >>> y = np.arange(3, dtype=np.float)
+ >>> y = np.arange(3, dtype=float)
>>> y
array([ 0., 1., 2.])
>>> np.ones_like(y)
@@ -279,13 +289,10 @@ def full(shape, fill_value, dtype=None, order='C'):
See Also
--------
- zeros_like : Return an array of zeros with shape and type of input.
- ones_like : Return an array of ones with shape and type of input.
- empty_like : Return an empty array with shape and type of input.
- full_like : Fill an array with shape and type of input.
- zeros : Return a new array setting values to zero.
- ones : Return a new array setting values to one.
+ full_like : Return a new array with shape of input filled with value.
empty : Return a new uninitialized array.
+ ones : Return a new array setting values to one.
+ zeros : Return a new array setting values to zero.
Examples
--------
@@ -334,17 +341,14 @@ def full_like(a, fill_value, dtype=None, order='K', subok=True):
See Also
--------
- zeros_like : Return an array of zeros with shape and type of input.
- ones_like : Return an array of ones with shape and type of input.
empty_like : Return an empty array with shape and type of input.
- zeros : Return a new array setting values to zero.
- ones : Return a new array setting values to one.
- empty : Return a new uninitialized array.
- full : Fill a new array.
+ ones_like : Return an array of ones with shape and type of input.
+ zeros_like : Return an array of zeros with shape and type of input.
+ full : Return a new array of given shape filled with value.
Examples
--------
- >>> x = np.arange(6, dtype=np.int)
+ >>> x = np.arange(6, dtype=int)
>>> np.full_like(x, 1)
array([1, 1, 1, 1, 1, 1])
>>> np.full_like(x, 0.1)
@@ -364,19 +368,6 @@ def full_like(a, fill_value, dtype=None, order='K', subok=True):
return res
-def extend_all(module):
- adict = {}
- for a in __all__:
- adict[a] = 1
- try:
- mall = getattr(module, '__all__')
- except AttributeError:
- mall = [k for k in module.__dict__.keys() if not k.startswith('_')]
- for a in mall:
- if a not in adict:
- __all__.append(a)
-
-
def count_nonzero(a, axis=None):
"""
Counts the number of non-zero values in the array ``a``.
@@ -425,39 +416,18 @@ def count_nonzero(a, axis=None):
array([2, 3])
"""
- if axis is None or axis == ():
+ if axis is None:
return multiarray.count_nonzero(a)
a = asanyarray(a)
- if a.dtype == bool:
- return a.sum(axis=axis, dtype=np.intp)
-
- if issubdtype(a.dtype, np.number):
- return (a != 0).sum(axis=axis, dtype=np.intp)
-
- if (issubdtype(a.dtype, np.string_) or
- issubdtype(a.dtype, np.unicode_)):
- nullstr = a.dtype.type('')
- return (a != nullstr).sum(axis=axis, dtype=np.intp)
-
- axis = asarray(_validate_axis(axis, a.ndim, 'axis'))
- counts = np.apply_along_axis(multiarray.count_nonzero, axis[0], a)
-
- if axis.size == 1:
- return counts
+ # TODO: this works around .astype(bool) not working properly (gh-9847)
+ if np.issubdtype(a.dtype, np.character):
+ a_bool = a != a.dtype.type()
else:
- # for subsequent axis numbers, that number decreases
- # by one in this new 'counts' array if it was larger
- # than the first axis upon which 'count_nonzero' was
- # applied but remains unchanged if that number was
- # smaller than that first axis
- #
- # this trick enables us to perform counts on object-like
- # elements across multiple axes very quickly because integer
- # addition is very well optimized
- return counts.sum(axis=tuple(axis[1:] - (
- axis[1:] > axis[0])), dtype=np.intp)
+ a_bool = a.astype(np.bool_, copy=False)
+
+ return a_bool.sum(axis=axis, dtype=np.intp)
def asarray(a, dtype=None, order=None):
@@ -519,9 +489,9 @@ def asarray(a, dtype=None, order=None):
Contrary to `asanyarray`, ndarray subclasses are not passed through:
- >>> issubclass(np.matrix, np.ndarray)
+ >>> issubclass(np.recarray, np.ndarray)
True
- >>> a = np.matrix([[1, 2]])
+ >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
>>> np.asarray(a) is a
False
>>> np.asanyarray(a) is a
@@ -575,7 +545,7 @@ def asanyarray(a, dtype=None, order=None):
Instances of `ndarray` subclasses are passed through as-is:
- >>> a = np.matrix([1, 2])
+ >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
>>> np.asanyarray(a) is a
True
@@ -705,6 +675,7 @@ def require(a, dtype=None, requirements=None):
OWNDATA : False
WRITEABLE : True
ALIGNED : True
+ WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
>>> y = np.require(x, dtype=np.float32, requirements=['A', 'O', 'W', 'F'])
@@ -714,15 +685,16 @@ def require(a, dtype=None, requirements=None):
OWNDATA : True
WRITEABLE : True
ALIGNED : True
+ WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
"""
- possible_flags = {'C':'C', 'C_CONTIGUOUS':'C', 'CONTIGUOUS':'C',
- 'F':'F', 'F_CONTIGUOUS':'F', 'FORTRAN':'F',
- 'A':'A', 'ALIGNED':'A',
- 'W':'W', 'WRITEABLE':'W',
- 'O':'O', 'OWNDATA':'O',
- 'E':'E', 'ENSUREARRAY':'E'}
+ possible_flags = {'C': 'C', 'C_CONTIGUOUS': 'C', 'CONTIGUOUS': 'C',
+ 'F': 'F', 'F_CONTIGUOUS': 'F', 'FORTRAN': 'F',
+ 'A': 'A', 'ALIGNED': 'A',
+ 'W': 'W', 'WRITEABLE': 'W',
+ 'O': 'O', 'OWNDATA': 'O',
+ 'E': 'E', 'ENSUREARRAY': 'E'}
if not requirements:
return asanyarray(a, dtype=dtype)
else:
@@ -838,7 +810,7 @@ def argwhere(a):
``np.argwhere(a)`` is the same as ``np.transpose(np.nonzero(a))``.
The output of ``argwhere`` is not suitable for indexing arrays.
- For this purpose use ``where(a)`` instead.
+ For this purpose use ``nonzero(a)`` instead.
Examples
--------
@@ -860,12 +832,12 @@ def flatnonzero(a):
"""
Return indices that are non-zero in the flattened version of a.
- This is equivalent to a.ravel().nonzero()[0].
+ This is equivalent to np.nonzero(np.ravel(a))[0].
Parameters
----------
- a : ndarray
- Input array.
+ a : array_like
+ Input data.
Returns
-------
@@ -893,7 +865,7 @@ def flatnonzero(a):
array([-2, -1, 1, 2])
"""
- return a.ravel().nonzero()[0]
+ return np.nonzero(np.ravel(a))[0]
_mode_from_name_dict = {'v': 0,
@@ -1038,7 +1010,8 @@ def convolve(a, v, mode='full'):
References
----------
- .. [1] Wikipedia, "Convolution", http://en.wikipedia.org/wiki/Convolution.
+ .. [1] Wikipedia, "Convolution",
+ https://en.wikipedia.org/wiki/Convolution
Examples
--------
@@ -1106,11 +1079,14 @@ def outer(a, b, out=None):
See also
--------
- inner, einsum
+ inner
+ einsum : ``einsum('i,j->ij', a.ravel(), b.ravel())`` is the equivalent.
+ ufunc.outer : A generalization to N dimensions and other operations.
+ ``np.multiply.outer(a.ravel(), b.ravel())`` is the equivalent.
References
----------
- .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd
+ .. [1] : G. H. Golub and C. F. Van Loan, *Matrix Computations*, 3rd
ed., Baltimore, MD, Johns Hopkins University Press, 1996,
pg. 8.
@@ -1151,63 +1127,7 @@ def outer(a, b, out=None):
"""
a = asarray(a)
b = asarray(b)
- return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out)
-
-
-def alterdot():
- """
- Change `dot`, `vdot`, and `inner` to use accelerated BLAS functions.
-
- Typically, as a user of NumPy, you do not explicitly call this
- function. If NumPy is built with an accelerated BLAS, this function is
- automatically called when NumPy is imported.
-
- When NumPy is built with an accelerated BLAS like ATLAS, these
- functions are replaced to make use of the faster implementations. The
- faster implementations only affect float32, float64, complex64, and
- complex128 arrays. Furthermore, the BLAS API only includes
- matrix-matrix, matrix-vector, and vector-vector products. Products of
- arrays with larger dimensionalities use the built in functions and are
- not accelerated.
-
- .. note:: Deprecated in NumPy 1.10.0
- The cblas functions have been integrated into the multarray
- module and alterdot now longer does anything. It will be
- removed in NumPy 1.11.0.
-
- See Also
- --------
- restoredot : `restoredot` undoes the effects of `alterdot`.
-
- """
- # 2014-08-13, 1.10
- warnings.warn("alterdot no longer does anything.",
- DeprecationWarning, stacklevel=2)
-
-
-def restoredot():
- """
- Restore `dot`, `vdot`, and `innerproduct` to the default non-BLAS
- implementations.
-
- Typically, the user will only need to call this when troubleshooting
- and installation problem, reproducing the conditions of a build without
- an accelerated BLAS, or when being very careful about benchmarking
- linear algebra operations.
-
- .. note:: Deprecated in NumPy 1.10.0
- The cblas functions have been integrated into the multarray
- module and restoredot now longer does anything. It will be
- removed in NumPy 1.11.0.
-
- See Also
- --------
- alterdot : `restoredot` undoes the effects of `alterdot`.
-
- """
- # 2014-08-13, 1.10
- warnings.warn("restoredot no longer does anything.",
- DeprecationWarning, stacklevel=2)
+ return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis, :], out)
def tensordot(a, b, axes=2):
@@ -1283,7 +1203,7 @@ def tensordot(a, b, axes=2):
[ True, True],
[ True, True],
[ True, True],
- [ True, True]], dtype=bool)
+ [ True, True]])
An extended example taking advantage of the overloading of + and \\*:
@@ -1334,7 +1254,7 @@ def tensordot(a, b, axes=2):
"""
try:
iter(axes)
- except:
+ except Exception:
axes_a = list(range(-axes, 0))
axes_b = list(range(0, axes))
else:
@@ -1354,9 +1274,9 @@ def tensordot(a, b, axes=2):
a, b = asarray(a), asarray(b)
as_ = a.shape
- nda = len(a.shape)
+ nda = a.ndim
bs = b.shape
- ndb = len(b.shape)
+ ndb = b.ndim
equal = True
if na != nb:
equal = False
@@ -1379,7 +1299,7 @@ def tensordot(a, b, axes=2):
N2 = 1
for axis in axes_a:
N2 *= as_[axis]
- newshape_a = (-1, N2)
+ newshape_a = (int(multiply.reduce([as_[ax] for ax in notin])), N2)
olda = [as_[axis] for axis in notin]
notin = [k for k in range(ndb) if k not in axes_b]
@@ -1387,7 +1307,7 @@ def tensordot(a, b, axes=2):
N2 = 1
for axis in axes_b:
N2 *= bs[axis]
- newshape_b = (N2, -1)
+ newshape_b = (N2, int(multiply.reduce([bs[ax] for ax in notin])))
oldb = [bs[axis] for axis in notin]
at = a.transpose(newaxes_a).reshape(newshape_a)
@@ -1460,16 +1380,14 @@ def roll(a, shift, axis=None):
return roll(a.ravel(), shift, 0).reshape(a.shape)
else:
+ axis = normalize_axis_tuple(axis, a.ndim, allow_duplicate=True)
broadcasted = broadcast(shift, axis)
- if len(broadcasted.shape) > 1:
+ if broadcasted.ndim > 1:
raise ValueError(
"'shift' and 'axis' should be scalars or 1D sequences")
shifts = {ax: 0 for ax in range(a.ndim)}
for sh, ax in broadcasted:
- if -a.ndim <= ax < a.ndim:
- shifts[ax % a.ndim] += sh
- else:
- raise ValueError("'axis' entry is out of bounds")
+ shifts[ax] += sh
rolls = [((slice(None), slice(None)),)] * a.ndim
for ax, offset in shifts.items():
@@ -1491,6 +1409,10 @@ def rollaxis(a, axis, start=0):
"""
Roll the specified axis backwards, until it lies in a given position.
+ This function continues to be supported for backward compatibility, but you
+ should prefer `moveaxis`. The `moveaxis` function was added in NumPy
+ 1.11.
+
Parameters
----------
a : ndarray
@@ -1527,15 +1449,12 @@ def rollaxis(a, axis, start=0):
"""
n = a.ndim
- if axis < 0:
- axis += n
+ axis = normalize_axis_index(axis, n)
if start < 0:
start += n
msg = "'%s' arg requires %d <= %s < %d, but %d was passed in"
- if not (0 <= axis < n):
- raise ValueError(msg % ('axis', -n, 'axis', n, axis))
if not (0 <= start < n + 1):
- raise ValueError(msg % ('start', -n, 'start', n + 1, start))
+ raise AxisError(msg % ('start', -n, 'start', n + 1, start))
if axis < start:
# it's been removed
start -= 1
@@ -1547,17 +1466,62 @@ def rollaxis(a, axis, start=0):
return a.transpose(axes)
-def _validate_axis(axis, ndim, argname):
- try:
- axis = [operator.index(axis)]
- except TypeError:
- axis = list(axis)
- axis = [a + ndim if a < 0 else a for a in axis]
- if not builtins.all(0 <= a < ndim for a in axis):
- raise ValueError('invalid axis for this array in `%s` argument' %
- argname)
- if len(set(axis)) != len(axis):
- raise ValueError('repeated axis in `%s` argument' % argname)
+def normalize_axis_tuple(axis, ndim, argname=None, allow_duplicate=False):
+ """
+ Normalizes an axis argument into a tuple of non-negative integer axes.
+
+ This handles shorthands such as ``1`` and converts them to ``(1,)``,
+ as well as performing the handling of negative indices covered by
+ `normalize_axis_index`.
+
+ By default, this forbids axes from being specified multiple times.
+
+ Used internally by multi-axis-checking logic.
+
+ .. versionadded:: 1.13.0
+
+ Parameters
+ ----------
+ axis : int, iterable of int
+ The un-normalized index or indices of the axis.
+ ndim : int
+ The number of dimensions of the array that `axis` should be normalized
+ against.
+ argname : str, optional
+ A prefix to put before the error message, typically the name of the
+ argument.
+ allow_duplicate : bool, optional
+ If False, the default, disallow an axis from being specified twice.
+
+ Returns
+ -------
+ normalized_axes : tuple of int
+ The normalized axis index, such that `0 <= normalized_axis < ndim`
+
+ Raises
+ ------
+ AxisError
+ If any axis provided is out of range
+ ValueError
+ If an axis is repeated
+
+ See also
+ --------
+ normalize_axis_index : normalizing a single scalar axis
+ """
+ # Optimization to speed-up the most common cases.
+ if type(axis) not in (tuple, list):
+ try:
+ axis = [operator.index(axis)]
+ except TypeError:
+ pass
+ # Going via an iterator directly is slower than via list comprehension.
+ axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis])
+ if not allow_duplicate and len(set(axis)) != len(axis):
+ if argname:
+ raise ValueError('repeated axis in `{}` argument'.format(argname))
+ else:
+ raise ValueError('repeated axis')
return axis
@@ -1567,7 +1531,7 @@ def moveaxis(a, source, destination):
Other axes remain in their original order.
- .. versionadded::1.11.0
+ .. versionadded:: 1.11.0
Parameters
----------
@@ -1602,7 +1566,7 @@ def moveaxis(a, source, destination):
>>> np.transpose(x).shape
(5, 4, 3)
- >>> np.swapaxis(x, 0, -1).shape
+ >>> np.swapaxes(x, 0, -1).shape
(5, 4, 3)
>>> np.moveaxis(x, [0, 1], [-1, -2]).shape
(5, 4, 3)
@@ -1617,8 +1581,8 @@ def moveaxis(a, source, destination):
a = asarray(a)
transpose = a.transpose
- source = _validate_axis(source, a.ndim, 'source')
- destination = _validate_axis(destination, a.ndim, 'destination')
+ source = normalize_axis_tuple(source, a.ndim, 'source')
+ destination = normalize_axis_tuple(destination, a.ndim, 'destination')
if len(source) != len(destination):
raise ValueError('`source` and `destination` arguments must have '
'the same number of elements')
@@ -1634,7 +1598,7 @@ def moveaxis(a, source, destination):
# fix hack in scipy which imports this function
def _move_axis_to_0(a, axis):
- return rollaxis(a, axis, 0)
+ return moveaxis(a, axis, 0)
def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
@@ -1755,14 +1719,12 @@ def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
a = asarray(a)
b = asarray(b)
# Check axisa and axisb are within bounds
- axis_msg = "'axis{0}' out of bounds"
- if axisa < -a.ndim or axisa >= a.ndim:
- raise ValueError(axis_msg.format('a'))
- if axisb < -b.ndim or axisb >= b.ndim:
- raise ValueError(axis_msg.format('b'))
+ axisa = normalize_axis_index(axisa, a.ndim, msg_prefix='axisa')
+ axisb = normalize_axis_index(axisb, b.ndim, msg_prefix='axisb')
+
# Move working axis to the end of the shape
- a = rollaxis(a, axisa, a.ndim)
- b = rollaxis(b, axisb, b.ndim)
+ a = moveaxis(a, axisa, -1)
+ b = moveaxis(b, axisb, -1)
msg = ("incompatible dimensions for cross product\n"
"(dimension must be 2 or 3)")
if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3):
@@ -1773,8 +1735,7 @@ def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
if a.shape[-1] == 3 or b.shape[-1] == 3:
shape += (3,)
# Check axisc is within bounds
- if axisc < -len(shape) or axisc >= len(shape):
- raise ValueError(axis_msg.format('c'))
+ axisc = normalize_axis_index(axisc, len(shape), msg_prefix='axisc')
dtype = promote_types(a.dtype, b.dtype)
cp = empty(shape, dtype)
@@ -1834,196 +1795,9 @@ def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
multiply(a0, b1, out=cp2)
cp2 -= a1 * b0
- # This works because we are moving the last axis
- return rollaxis(cp, -1, axisc)
-
-
-# Use numarray's printing function
-from .arrayprint import array2string, get_printoptions, set_printoptions
-
-
-_typelessdata = [int_, float_, complex_]
-if issubclass(intc, int):
- _typelessdata.append(intc)
+ return moveaxis(cp, -1, axisc)
-if issubclass(longlong, int):
- _typelessdata.append(longlong)
-
-
-def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):
- """
- Return the string representation of an array.
-
- Parameters
- ----------
- arr : ndarray
- Input array.
- max_line_width : int, optional
- The maximum number of columns the string should span. Newline
- characters split the string appropriately after array elements.
- precision : int, optional
- Floating point precision. Default is the current printing precision
- (usually 8), which can be altered using `set_printoptions`.
- suppress_small : bool, optional
- Represent very small numbers as zero, default is False. Very small
- is defined by `precision`, if the precision is 8 then
- numbers smaller than 5e-9 are represented as zero.
-
- Returns
- -------
- string : str
- The string representation of an array.
-
- See Also
- --------
- array_str, array2string, set_printoptions
-
- Examples
- --------
- >>> np.array_repr(np.array([1,2]))
- 'array([1, 2])'
- >>> np.array_repr(np.ma.array([0.]))
- 'MaskedArray([ 0.])'
- >>> np.array_repr(np.array([], np.int32))
- 'array([], dtype=int32)'
-
- >>> x = np.array([1e-6, 4e-7, 2, 3])
- >>> np.array_repr(x, precision=6, suppress_small=True)
- 'array([ 0.000001, 0. , 2. , 3. ])'
-
- """
- if arr.size > 0 or arr.shape == (0,):
- lst = array2string(arr, max_line_width, precision, suppress_small,
- ', ', "array(")
- else: # show zero-length shape unless it is (0,)
- lst = "[], shape=%s" % (repr(arr.shape),)
-
- if arr.__class__ is not ndarray:
- cName = arr.__class__.__name__
- else:
- cName = "array"
-
- skipdtype = (arr.dtype.type in _typelessdata) and arr.size > 0
-
- if skipdtype:
- return "%s(%s)" % (cName, lst)
- else:
- typename = arr.dtype.name
- # Quote typename in the output if it is "complex".
- if typename and not (typename[0].isalpha() and typename.isalnum()):
- typename = "'%s'" % typename
-
- lf = ''
- if issubclass(arr.dtype.type, flexible):
- if arr.dtype.names:
- typename = "%s" % str(arr.dtype)
- else:
- typename = "'%s'" % str(arr.dtype)
- lf = '\n'+' '*len("array(")
- return cName + "(%s, %sdtype=%s)" % (lst, lf, typename)
-
-
-def array_str(a, max_line_width=None, precision=None, suppress_small=None):
- """
- Return a string representation of the data in an array.
-
- The data in the array is returned as a single string. This function is
- similar to `array_repr`, the difference being that `array_repr` also
- returns information on the kind of array and its data type.
-
- Parameters
- ----------
- a : ndarray
- Input array.
- max_line_width : int, optional
- Inserts newlines if text is longer than `max_line_width`. The
- default is, indirectly, 75.
- precision : int, optional
- Floating point precision. Default is the current printing precision
- (usually 8), which can be altered using `set_printoptions`.
- suppress_small : bool, optional
- Represent numbers "very close" to zero as zero; default is False.
- Very close is defined by precision: if the precision is 8, e.g.,
- numbers smaller (in absolute value) than 5e-9 are represented as
- zero.
-
- See Also
- --------
- array2string, array_repr, set_printoptions
-
- Examples
- --------
- >>> np.array_str(np.arange(3))
- '[0 1 2]'
-
- """
- return array2string(a, max_line_width, precision, suppress_small, ' ', "", str)
-
-
-def set_string_function(f, repr=True):
- """
- Set a Python function to be used when pretty printing arrays.
-
- Parameters
- ----------
- f : function or None
- Function to be used to pretty print arrays. The function should expect
- a single array argument and return a string of the representation of
- the array. If None, the function is reset to the default NumPy function
- to print arrays.
- repr : bool, optional
- If True (default), the function for pretty printing (``__repr__``)
- is set, if False the function that returns the default string
- representation (``__str__``) is set.
-
- See Also
- --------
- set_printoptions, get_printoptions
-
- Examples
- --------
- >>> def pprint(arr):
- ... return 'HA! - What are you going to do now?'
- ...
- >>> np.set_string_function(pprint)
- >>> a = np.arange(10)
- >>> a
- HA! - What are you going to do now?
- >>> print(a)
- [0 1 2 3 4 5 6 7 8 9]
-
- We can reset the function to the default:
-
- >>> np.set_string_function(None)
- >>> a
- array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
-
- `repr` affects either pretty printing or normal string representation.
- Note that ``__repr__`` is still affected by setting ``__str__``
- because the width of each array element in the returned string becomes
- equal to the length of the result of ``__str__()``.
-
- >>> x = np.arange(4)
- >>> np.set_string_function(lambda x:'random', repr=False)
- >>> x.__str__()
- 'random'
- >>> x.__repr__()
- 'array([ 0, 1, 2, 3])'
-
- """
- if f is None:
- if repr:
- return multiarray.set_string_function(array_repr, 1)
- else:
- return multiarray.set_string_function(array_str, 0)
- else:
- return multiarray.set_string_function(f, repr)
-
-
-set_string_function(array_str, 0)
-set_string_function(array_repr, 1)
-
little_endian = (sys.byteorder == 'little')
@@ -2089,15 +1863,12 @@ def indices(dimensions, dtype=int):
"""
dimensions = tuple(dimensions)
N = len(dimensions)
- if N == 0:
- return array([], dtype=dtype)
+ shape = (1,)*N
res = empty((N,)+dimensions, dtype=dtype)
for i, dim in enumerate(dimensions):
- tmp = arange(dim, dtype=dtype)
- tmp.shape = (1,)*i + (dim,)+(1,)*(N-i-1)
- newdim = dimensions[:i] + (1,) + dimensions[i+1:]
- val = zeros(newdim, dtype)
- add(tmp, val, res[i])
+ res[i] = arange(dim, dtype=dtype).reshape(
+ shape[:i] + (dim,) + shape[i+1:]
+ )
return res
@@ -2114,8 +1885,8 @@ def fromfunction(function, shape, **kwargs):
The function is called with N parameters, where N is the rank of
`shape`. Each parameter represents the coordinates of the array
varying along a specific axis. For example, if `shape`
- were ``(2, 2)``, then the parameters in turn be (0, 0), (0, 1),
- (1, 0), (1, 1).
+ were ``(2, 2)``, then the parameters would be
+ ``array([[0, 0], [1, 1]])`` and ``array([[0, 1], [0, 1]])``
shape : (N,) tuple of ints
Shape of the output array, which also determines the shape of
the coordinate arrays passed to `function`.
@@ -2129,7 +1900,7 @@ def fromfunction(function, shape, **kwargs):
The result of the call to `function` is passed back directly.
Therefore the shape of `fromfunction` is completely determined by
`function`. If `function` returns a scalar value, the shape of
- `fromfunction` would match the `shape` parameter.
+ `fromfunction` would not match the `shape` parameter.
See Also
--------
@@ -2144,7 +1915,7 @@ def fromfunction(function, shape, **kwargs):
>>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
array([[ True, False, False],
[False, True, False],
- [False, False, True]], dtype=bool)
+ [False, False, True]])
>>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
array([[0, 1, 2],
@@ -2179,12 +1950,22 @@ def isscalar(num):
False
>>> np.isscalar(False)
True
+ >>> np.isscalar('numpy')
+ True
+
+ NumPy supports PEP 3141 numbers:
+
+ >>> from fractions import Fraction
+ >>> isscalar(Fraction(5, 17))
+ True
+ >>> from numbers import Number
+ >>> isscalar(Number())
+ True
"""
- if isinstance(num, generic):
- return True
- else:
- return type(num) in ScalarType
+ return (isinstance(num, generic)
+ or type(num) in ScalarType
+ or isinstance(num, numbers.Number))
def binary_repr(num, width=None):
@@ -2212,7 +1993,7 @@ def binary_repr(num, width=None):
designated form.
If the `width` value is insufficient, it will be ignored, and `num` will
- be returned in binary(`num` > 0) or two's complement (`num` < 0) form
+ be returned in binary (`num` > 0) or two's complement (`num` < 0) form
with its width equal to the minimum number of bits needed to represent
the number in the designated form. This behavior is deprecated and will
later raise an error.
@@ -2238,7 +2019,7 @@ def binary_repr(num, width=None):
References
----------
.. [1] Wikipedia, "Two's complement",
- http://en.wikipedia.org/wiki/Two's_complement
+ https://en.wikipedia.org/wiki/Two's_complement
Examples
--------
@@ -2258,7 +2039,7 @@ def binary_repr(num, width=None):
'11101'
"""
- def warn_if_insufficient(width, binwdith):
+ def warn_if_insufficient(width, binwidth):
if width is not None and width < binwidth:
warnings.warn(
"Insufficient bit width provided. This behavior "
@@ -2282,10 +2063,16 @@ def binary_repr(num, width=None):
else:
poswidth = len(bin(-num)[2:])
- twocomp = 2**(poswidth + 1) + num
+ # See gh-8679: remove extra digit
+ # for numbers at boundaries.
+ if 2**(poswidth - 1) == -num:
+ poswidth -= 1
+
+ twocomp = 2**(poswidth + 1) + num
binary = bin(twocomp)[2:]
binwidth = len(binary)
+
outwidth = max(binwidth, width)
warn_if_insufficient(width, binwidth)
return '1' * (outwidth - binwidth) + binary
@@ -2361,6 +2148,10 @@ def load(file):
load, save
"""
+ # NumPy 1.15.0, 2017-12-10
+ warnings.warn(
+ "np.core.numeric.load is deprecated, use pickle.load instead",
+ DeprecationWarning, stacklevel=2)
if isinstance(file, type("")):
file = open(file, "rb")
return pickle.load(file)
@@ -2448,7 +2239,7 @@ def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
See Also
--------
- isclose, all, any
+ isclose, all, any, equal
Notes
-----
@@ -2458,9 +2249,14 @@ def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
The above equation is not symmetric in `a` and `b`, so that
- `allclose(a, b)` might be different from `allclose(b, a)` in
+ ``allclose(a, b)`` might be different from ``allclose(b, a)`` in
some rare cases.
+ The comparison of `a` and `b` uses standard broadcasting, which
+ means that `a` and `b` need not have the same shape in order for
+ ``allclose(a, b)`` to evaluate to True. The same is true for
+ `equal` but not `array_equal`.
+
Examples
--------
>>> np.allclose([1e10,1e-7], [1.00001e10,1e-8])
@@ -2489,6 +2285,9 @@ def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
`atol` are added together to compare against the absolute difference
between `a` and `b`.
+ .. warning:: The default `atol` is not appropriate for comparing numbers
+ that are much smaller than one (see Notes).
+
Parameters
----------
a, b : array_like
@@ -2521,9 +2320,15 @@ def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
- The above equation is not symmetric in `a` and `b`, so that
- `isclose(a, b)` might be different from `isclose(b, a)` in
- some rare cases.
+ Unlike the built-in `math.isclose`, the above equation is not symmetric
+ in `a` and `b` -- it assumes `b` is the reference value -- so that
+ `isclose(a, b)` might be different from `isclose(b, a)`. Furthermore,
+ the default value of atol is not zero, and is used to determine what
+ small values should be considered close to zero. The default value is
+ appropriate for expected values of order unity: if the expected values
+ are significantly smaller than one, it can result in false positives.
+ `atol` should be carefully selected for the use case at hand. A zero value
+ for `atol` will result in `False` if either `a` or `b` is zero.
Examples
--------
@@ -2537,16 +2342,21 @@ def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
array([True, False])
>>> np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
array([True, True])
+ >>> np.isclose([1e-8, 1e-7], [0.0, 0.0])
+ array([ True, False], dtype=bool)
+ >>> np.isclose([1e-100, 1e-7], [0.0, 0.0], atol=0.0)
+ array([False, False], dtype=bool)
+ >>> np.isclose([1e-10, 1e-10], [1e-20, 0.0])
+ array([ True, True], dtype=bool)
+ >>> np.isclose([1e-10, 1e-10], [1e-20, 0.999999e-10], atol=0.0)
+ array([False, True], dtype=bool)
"""
def within_tol(x, y, atol, rtol):
with errstate(invalid='ignore'):
- result = less_equal(abs(x-y), atol + rtol * abs(y))
- if isscalar(a) and isscalar(b):
- result = bool(result)
- return result
+ return less_equal(abs(x-y), atol + rtol * abs(y))
- x = array(a, copy=False, subok=True, ndmin=1)
- y = array(b, copy=False, subok=True, ndmin=1)
+ x = asanyarray(a)
+ y = asanyarray(b)
# Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT).
# This will cause casting of x later. Also, make sure to allow subclasses
@@ -2573,12 +2383,11 @@ def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
if equal_nan:
# Make NaN == NaN
both_nan = isnan(x) & isnan(y)
+
+ # Needed to treat masked arrays correctly. = True would not work.
cond[both_nan] = both_nan[both_nan]
- if isscalar(a) and isscalar(b):
- return bool(cond)
- else:
- return cond
+ return cond[()] # Flatten 0d arrays to scalars
def array_equal(a1, a2):
@@ -2616,7 +2425,7 @@ def array_equal(a1, a2):
"""
try:
a1, a2 = asarray(a1), asarray(a2)
- except:
+ except Exception:
return False
if a1.shape != a2.shape:
return False
@@ -2660,22 +2469,22 @@ def array_equiv(a1, a2):
"""
try:
a1, a2 = asarray(a1), asarray(a2)
- except:
+ except Exception:
return False
try:
multiarray.broadcast(a1, a2)
- except:
+ except Exception:
return False
return bool(asarray(a1 == a2).all())
-_errdict = {"ignore":ERR_IGNORE,
- "warn":ERR_WARN,
- "raise":ERR_RAISE,
- "call":ERR_CALL,
- "print":ERR_PRINT,
- "log":ERR_LOG}
+_errdict = {"ignore": ERR_IGNORE,
+ "warn": ERR_WARN,
+ "raise": ERR_RAISE,
+ "call": ERR_CALL,
+ "print": ERR_PRINT,
+ "log": ERR_LOG}
_errdict_rev = {}
for key in _errdict.keys():
@@ -2724,7 +2533,7 @@ def seterr(all=None, divide=None, over=None, under=None, invalid=None):
Notes
-----
- The floating-point exceptions are defined in the IEEE 754 standard [1]:
+ The floating-point exceptions are defined in the IEEE 754 standard [1]_:
- Division by zero: infinite result obtained from finite numbers.
- Overflow: result too large to be expressed.
@@ -2733,7 +2542,7 @@ def seterr(all=None, divide=None, over=None, under=None, invalid=None):
- Invalid operation: result is not an expressible number, typically
indicates that a NaN was produced.
- .. [1] http://en.wikipedia.org/wiki/IEEE_754
+ .. [1] https://en.wikipedia.org/wiki/IEEE_754
Examples
--------
@@ -2742,7 +2551,8 @@ def seterr(all=None, divide=None, over=None, under=None, invalid=None):
{'over': 'ignore', 'divide': 'ignore', 'invalid': 'ignore',
'under': 'ignore'}
>>> np.seterr(**old_settings) # reset to default
- {'over': 'raise', 'divide': 'ignore', 'invalid': 'ignore', 'under': 'ignore'}
+ {'over': 'raise', 'divide': 'ignore', 'invalid': 'ignore',
+ 'under': 'ignore'}
>>> np.int16(32000) * np.int16(3)
30464
@@ -2889,11 +2699,11 @@ def seterrcall(func):
Function to call upon floating-point errors ('call'-mode) or
object whose 'write' method is used to log such message ('log'-mode).
- The call function takes two arguments. The first is a string describing the
- type of error (such as "divide by zero", "overflow", "underflow", or "invalid value"),
- and the second is the status flag. The flag is a byte, whose four
- least-significant bits indicate the type of error, one of "divide", "over",
- "under", "invalid"::
+ The call function takes two arguments. The first is a string describing
+ the type of error (such as "divide by zero", "overflow", "underflow",
+ or "invalid value"), and the second is the status flag. The flag is a
+ byte, whose four least-significant bits indicate the type of error, one
+ of "divide", "over", "under", "invalid"::
[0 0 0 0 divide over under invalid]
@@ -2953,8 +2763,8 @@ def seterrcall(func):
{'over': 'log', 'divide': 'log', 'invalid': 'log', 'under': 'log'}
"""
- if func is not None and not isinstance(func, collections.Callable):
- if not hasattr(func, 'write') or not isinstance(func.write, collections.Callable):
+ if func is not None and not isinstance(func, collections_abc.Callable):
+ if not hasattr(func, 'write') or not isinstance(func.write, collections_abc.Callable):
raise ValueError("Only callable can be used as callback")
pyvals = umath.geterrobj()
old = geterrcall()
@@ -3010,6 +2820,8 @@ def geterrcall():
class _unspecified(object):
pass
+
+
_Unspecified = _unspecified()
@@ -3104,10 +2916,25 @@ nan = NaN = NAN
False_ = bool_(False)
True_ = bool_(True)
+
+def extend_all(module):
+ existing = set(__all__)
+ try:
+ mall = getattr(module, '__all__')
+ except AttributeError:
+ mall = [k for k in module.__dict__.keys() if not k.startswith('_')]
+ for a in mall:
+ if a not in existing:
+ __all__.append(a)
+
+
from .umath import *
from .numerictypes import *
from . import fromnumeric
from .fromnumeric import *
+from . import arrayprint
+from .arrayprint import *
extend_all(fromnumeric)
extend_all(umath)
extend_all(numerictypes)
+extend_all(arrayprint)