From 250861059b106371cb232456eeccd6d9e97d8f00 Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Wed, 14 Nov 2018 11:36:59 -0800 Subject: TST, DOC: enable refguide_check * ported the refguide_check module from SciPy for usage in NumPy docstring execution/ verification; added the refguide_check run to Azure Mac OS CI * adjusted NumPy docstrings such that refguide_check passes --- numpy/core/fromnumeric.py | 71 ++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 32 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 59a820d53..33ecd6905 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -240,12 +240,16 @@ def reshape(a, newshape, order='C'): you should assign the new shape to the shape attribute of the array:: >>> a = np.zeros((10, 2)) + # A transpose makes the array non-contiguous >>> b = a.T + # Taking a view makes it possible to modify the shape without modifying # the initial object. >>> c = b.view() >>> c.shape = (20) + Traceback (most recent call last): + ... AttributeError: incompatible shape for a non-contiguous array The `order` keyword gives the index ordering both for *fetching* the values @@ -1641,27 +1645,27 @@ def ravel(a, order='C'): Examples -------- - It is equivalent to ``reshape(-1, order=order)``. + >>> # It is equivalent to ``reshape(-1, order=order)``. >>> x = np.array([[1, 2, 3], [4, 5, 6]]) - >>> print(np.ravel(x)) - [1 2 3 4 5 6] + >>> np.ravel(x) + array([1, 2, 3, 4, 5, 6]) - >>> print(x.reshape(-1)) - [1 2 3 4 5 6] + >>> x.reshape(-1) + array([1, 2, 3, 4, 5, 6]) - >>> print(np.ravel(x, order='F')) - [1 4 2 5 3 6] + >>> np.ravel(x, order='F') + array([1, 4, 2, 5, 3, 6]) - When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering: + >>> # When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering: - >>> print(np.ravel(x.T)) - [1 4 2 5 3 6] - >>> print(np.ravel(x.T, order='A')) - [1 2 3 4 5 6] + >>> np.ravel(x.T) + array([1, 4, 2, 5, 3, 6]) + >>> np.ravel(x.T, order='A') + array([1, 2, 3, 4, 5, 6]) - When ``order`` is 'K', it will preserve orderings that are neither 'C' - nor 'F', but won't reverse axes: + >>> # When ``order`` is 'K', it will preserve orderings that are neither 'C' + >>> # nor 'F', but won't reverse axes: >>> a = np.arange(3)[::-1]; a array([2, 1, 0]) @@ -1747,7 +1751,7 @@ def nonzero(a): array([[0, 0], [1, 1], [2, 0], - [2, 1]) + [2, 1]]) A common use for ``nonzero`` is to find the indices of an array, where a condition is True. Given an array `a`, the condition `a` > 3 is a @@ -2150,10 +2154,10 @@ def any(a, axis=None, out=None, keepdims=np._NoValue): >>> np.any(np.nan) True - >>> o=np.array([False]) + >>> o=np.array(False) >>> z=np.any([-1, 4, 5], out=o) >>> z, o - (array([ True]), array([ True])) + (array(True), array(True)) >>> # Check now that z is a reference to o >>> z is o True @@ -2238,6 +2242,9 @@ def all(a, axis=None, out=None, keepdims=np._NoValue): >>> o=np.array([False]) >>> z=np.all([-1, 4, 5], out=o) + Traceback (most recent call last): + ... + ValueError: output parameter for reduction operation logical_and has too many dimensions >>> id(z), id(o), z # doctest: +SKIP (28293632, 28293632, array([ True])) @@ -2724,8 +2731,8 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._N raised on overflow. That means that, on a 32-bit platform: >>> x = np.array([536870910, 536870910, 536870910, 536870910]) - >>> np.prod(x) # random - 16 + >>> np.prod(x) + 6917529010461212688 # may vary The product of an empty array is the neutral element 1: @@ -2993,11 +3000,11 @@ def around(a, decimals=0, out=None): Examples -------- >>> np.around([0.37, 1.64]) - array([ 0., 2.]) + array([0., 2.]) >>> np.around([0.37, 1.64], decimals=1) - array([ 0.4, 1.6]) + array([0.4, 1.6]) >>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value - array([ 0., 2., 2., 4., 4.]) + array([0., 2., 2., 4., 4.]) >>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned array([ 1, 2, 3, 11]) >>> np.around([1,2,3,11], decimals=-1) @@ -3085,9 +3092,9 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): >>> np.mean(a) 2.5 >>> np.mean(a, axis=0) - array([ 2., 3.]) + array([2., 3.]) >>> np.mean(a, axis=1) - array([ 1.5, 3.5]) + array([1.5, 3.5]) In single precision, `mean` can be inaccurate: @@ -3100,7 +3107,7 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): Computing the mean in float64 is more accurate: >>> np.mean(a, dtype=np.float64) - 0.55000000074505806 + 0.55000000074505806 # may vary """ kwargs = {} @@ -3206,11 +3213,11 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): -------- >>> a = np.array([[1, 2], [3, 4]]) >>> np.std(a) - 1.1180339887498949 + 1.1180339887498949 # may vary >>> np.std(a, axis=0) - array([ 1., 1.]) + array([1., 1.]) >>> np.std(a, axis=1) - array([ 0.5, 0.5]) + array([0.5, 0.5]) In single precision, std() can be inaccurate: @@ -3223,7 +3230,7 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): Computing the standard deviation in float64 is more accurate: >>> np.std(a, dtype=np.float64) - 0.44999999925494177 + 0.44999999925494177 # may vary """ kwargs = {} @@ -3330,9 +3337,9 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): >>> np.var(a) 1.25 >>> np.var(a, axis=0) - array([ 1., 1.]) + array([1., 1.]) >>> np.var(a, axis=1) - array([ 0.25, 0.25]) + array([0.25, 0.25]) In single precision, var() can be inaccurate: @@ -3345,7 +3352,7 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): Computing the variance in float64 is more accurate: >>> np.var(a, dtype=np.float64) - 0.20249999932944759 + 0.20249999932944759 # may vary >>> ((1-0.55)**2 + (0.1-0.55)**2)/2 0.2025 -- cgit v1.2.1 From 19784177a61de75927a4934fd4cdd91afbb5b35c Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Tue, 4 Dec 2018 12:17:59 -0800 Subject: MAINT: address several reviewer comments --- numpy/core/fromnumeric.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 33ecd6905..575e0a8ef 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2240,13 +2240,10 @@ def all(a, axis=None, out=None, keepdims=np._NoValue): >>> np.all([1.0, np.nan]) True - >>> o=np.array([False]) + >>> o=np.array(False) >>> z=np.all([-1, 4, 5], out=o) - Traceback (most recent call last): - ... - ValueError: output parameter for reduction operation logical_and has too many dimensions - >>> id(z), id(o), z # doctest: +SKIP - (28293632, 28293632, array([ True])) + >>> id(z), id(o), z + (28293632, 28293632, array([ True])) # may vary """ return _wrapreduction(a, np.logical_and, 'all', axis, None, out, keepdims=keepdims) @@ -2732,7 +2729,7 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._N >>> x = np.array([536870910, 536870910, 536870910, 536870910]) >>> np.prod(x) - 6917529010461212688 # may vary + 16 # may vary The product of an empty array is the neutral element 1: -- cgit v1.2.1 From 0bdc587d6cf5e6806e95d9debcafe62ac9f1d7fa Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Wed, 5 Dec 2018 11:15:28 -0800 Subject: MAINT: addressing review comments * restored regression comment in numpy/core/defchararray.py * fixed the dimensionality of the z array in all() docstring in numpy/core/fromnumeric.py; this isn't detected because it is in-line with variable memory addresses which are tagged as variable for refguide * byte_bounds() docstring adjusted to reflect non-variable dtype after reviewer requested removal of complex dtype * restore an original comment in matmul docstring, as requested by reviewer --- numpy/core/fromnumeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 575e0a8ef..474556b30 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2243,7 +2243,7 @@ def all(a, axis=None, out=None, keepdims=np._NoValue): >>> o=np.array(False) >>> z=np.all([-1, 4, 5], out=o) >>> id(z), id(o), z - (28293632, 28293632, array([ True])) # may vary + (28293632, 28293632, array(True)) # may vary """ return _wrapreduction(a, np.logical_and, 'all', axis, None, out, keepdims=keepdims) -- cgit v1.2.1 From 577a86e30014382c3fed1319379caa8728842543 Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Wed, 5 Dec 2018 11:48:11 -0800 Subject: MAINT: >>> # style cleanups requested * reviewer requested that the cases where I switched from free-floating comments to `>>> # comments` be reverted to free-floating in docstrings --- numpy/core/fromnumeric.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 474556b30..240eac6ce 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1645,7 +1645,7 @@ def ravel(a, order='C'): Examples -------- - >>> # It is equivalent to ``reshape(-1, order=order)``. + It is equivalent to ``reshape(-1, order=order)``. >>> x = np.array([[1, 2, 3], [4, 5, 6]]) >>> np.ravel(x) @@ -1657,15 +1657,15 @@ def ravel(a, order='C'): >>> np.ravel(x, order='F') array([1, 4, 2, 5, 3, 6]) - >>> # When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering: + When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering: >>> np.ravel(x.T) array([1, 4, 2, 5, 3, 6]) >>> np.ravel(x.T, order='A') array([1, 2, 3, 4, 5, 6]) - >>> # When ``order`` is 'K', it will preserve orderings that are neither 'C' - >>> # nor 'F', but won't reverse axes: + When ``order`` is 'K', it will preserve orderings that are neither 'C' + nor 'F', but won't reverse axes: >>> a = np.arange(3)[::-1]; a array([2, 1, 0]) -- cgit v1.2.1 From 5afe650403bdb3aa1a3189c1b8c3233501208521 Mon Sep 17 00:00:00 2001 From: Marten van Kerkwijk Date: Sun, 10 Dec 2017 14:32:40 -0500 Subject: ENH: allow where in reduce operations. In this implementation, if the ufunc does not have an identity, it needs an initial vavlue to be supplied. --- numpy/core/fromnumeric.py | 79 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 19 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 240eac6ce..d94372986 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -243,7 +243,7 @@ def reshape(a, newshape, order='C'): # A transpose makes the array non-contiguous >>> b = a.T - + # Taking a view makes it possible to modify the shape without modifying # the initial object. >>> c = b.view() @@ -1452,7 +1452,7 @@ def diagonal(a, offset=0, axis1=0, axis2=1): same type as `a` is returned unless `a` is a `matrix`, in which case a 1-D array rather than a (2-D) `matrix` is returned in order to maintain backward compatibility. - + If ``a.ndim > 2``, then the dimensions specified by `axis1` and `axis2` are removed, and a new axis inserted at the end corresponding to the diagonal. @@ -1963,12 +1963,13 @@ def clip(a, a_min, a_max, out=None): def _sum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, - initial=None): + initial=None, where=None): return (a, out) @array_function_dispatch(_sum_dispatcher) -def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue): +def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, + initial=np._NoValue, where=np._NoValue): """ Sum of array elements over a given axis. @@ -2012,6 +2013,11 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._No .. versionadded:: 1.15.0 + where : array_like of bool, optional + Elements to include in the sum. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.17.0 + Returns ------- sum_along_axis : ndarray @@ -2052,6 +2058,8 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._No array([0, 6]) >>> np.sum([[0, 1], [0, 5]], axis=1) array([1, 5]) + >>> np.sum([[0, 1], [np.nan, 5]], where=[False, True], axis=1) + array([1., 5.]) If the accumulator is too small, overflow occurs: @@ -2077,7 +2085,7 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._No return res return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims, - initial=initial) + initial=initial, where=where) def _any_dispatcher(a, axis=None, out=None, keepdims=None): @@ -2394,12 +2402,14 @@ def ptp(a, axis=None, out=None, keepdims=np._NoValue): return _methods._ptp(a, axis=axis, out=out, **kwargs) -def _amax_dispatcher(a, axis=None, out=None, keepdims=None, initial=None): +def _amax_dispatcher(a, axis=None, out=None, keepdims=None, initial=None, + where=None): return (a, out) @array_function_dispatch(_amax_dispatcher) -def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): +def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue, + where=np._NoValue): """ Return the maximum of an array or maximum along an axis. @@ -2437,6 +2447,11 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): .. versionadded:: 1.15.0 + where : array_like of bool, optional + Elements to compare for the maximum. See `~numpy.ufunc.reduce` + for details. + + .. versionadded:: 1.17.0 Returns ------- @@ -2482,11 +2497,14 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): array([2, 3]) >>> np.amax(a, axis=1) # Maxima along the second axis array([1, 3]) - + >>> np.amax(a, where=[False, True], initial=-1, axis=0) + array([-1, 3]) >>> b = np.arange(5, dtype=float) >>> b[2] = np.NaN >>> np.amax(b) nan + >>> np.amax(b, where=~np.isnan(b), initial=-1) + 4.0 >>> np.nanmax(b) 4.0 @@ -2505,16 +2523,18 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): >>> max([5], default=6) 5 """ - return _wrapreduction(a, np.maximum, 'max', axis, None, out, keepdims=keepdims, - initial=initial) + return _wrapreduction(a, np.maximum, 'max', axis, None, out, + keepdims=keepdims, initial=initial, where=where) -def _amin_dispatcher(a, axis=None, out=None, keepdims=None, initial=None): +def _amin_dispatcher(a, axis=None, out=None, keepdims=None, initial=None, + where=None): return (a, out) @array_function_dispatch(_amin_dispatcher) -def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): +def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue, + where=np._NoValue): """ Return the minimum of an array or minimum along an axis. @@ -2552,6 +2572,12 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): .. versionadded:: 1.15.0 + where : array_like of bool, optional + Elements to compare for the minimum. See `~numpy.ufunc.reduce` + for details. + + .. versionadded:: 1.17.0 + Returns ------- amin : ndarray or scalar @@ -2596,11 +2622,15 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): array([0, 1]) >>> np.amin(a, axis=1) # Minima along the second axis array([0, 2]) + >>> np.amin(a, where=[False, True], initial=10, axis=0) + array([10, 1]) >>> b = np.arange(5, dtype=float) >>> b[2] = np.NaN >>> np.amin(b) nan + >>> np.amin(b, where=~np.isnan(b), initial=10) + 0.0 >>> np.nanmin(b) 0.0 @@ -2618,8 +2648,8 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): >>> min([6], default=5) 6 """ - return _wrapreduction(a, np.minimum, 'min', axis, None, out, keepdims=keepdims, - initial=initial) + return _wrapreduction(a, np.minimum, 'min', axis, None, out, + keepdims=keepdims, initial=initial, where=where) def _alen_dispathcer(a): @@ -2660,13 +2690,14 @@ def alen(a): return len(array(a, ndmin=1)) -def _prod_dispatcher( - a, axis=None, dtype=None, out=None, keepdims=None, initial=None): +def _prod_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, + initial=None, where=None): return (a, out) @array_function_dispatch(_prod_dispatcher) -def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue): +def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, + initial=np._NoValue, where=np._NoValue): """ Return the product of array elements over a given axis. @@ -2711,6 +2742,11 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._N .. versionadded:: 1.15.0 + where : array_like of bool, optional + Elements to include in the product. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.17.0 + Returns ------- product_along_axis : ndarray, see `dtype` parameter above. @@ -2753,6 +2789,11 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._N >>> np.prod([[1.,2.],[3.,4.]], axis=1) array([ 2., 12.]) + Or select specific elements to include: + + >>> np.prod([1., np.nan, 3.], where=[True, False, True]) + 3.0 + If the type of `x` is unsigned, then the output type is the unsigned platform integer: @@ -2772,8 +2813,8 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._N >>> np.prod([1, 2], initial=5) 10 """ - return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out, keepdims=keepdims, - initial=initial) + return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out, + keepdims=keepdims, initial=initial, where=where) def _cumprod_dispatcher(a, axis=None, dtype=None, out=None): -- cgit v1.2.1 From 5298b464f31bca533cbdb928916a7d5df49707c0 Mon Sep 17 00:00:00 2001 From: wtli Date: Mon, 21 Jan 2019 21:46:44 +0800 Subject: DOC: add docstring for timsort --- numpy/core/fromnumeric.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index d94372986..7865dbf64 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -828,7 +828,7 @@ def sort(a, axis=-1, kind='quicksort', order=None): axis : int or None, optional Axis along which to sort. If None, the array is flattened before sorting. The default is -1, which sorts along the last axis. - kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + kind : {'quicksort', 'mergesort', 'heapsort', 'timsort', 'stable'}, optional Sorting algorithm. Default is 'quicksort'. order : str or list of str, optional When `a` is an array with fields defined, this argument specifies @@ -855,7 +855,7 @@ def sort(a, axis=-1, kind='quicksort', order=None): The various sorting algorithms are characterized by their average speed, worst case performance, work space size, and whether they are stable. A stable sort keeps items with the same key in the same relative - order. The three available algorithms have the following + order. The four available algorithms have the following properties: =========== ======= ============= ============ ======== @@ -864,6 +864,7 @@ def sort(a, axis=-1, kind='quicksort', order=None): 'quicksort' 1 O(n^2) 0 no 'mergesort' 2 O(n*log(n)) ~n/2 yes 'heapsort' 3 O(n*log(n)) 0 no + 'timsort' 2 O(n*log(n)) ~n/2 yes =========== ======= ============= ============ ======== All the sort algorithms make temporary copies of the data when @@ -897,6 +898,13 @@ def sort(a, axis=-1, kind='quicksort', order=None): for the data type being sorted. It is currently mapped to merge sort. + .. versionadded:: 1.17.0 + Timsort is added for better performance on already or nearly + sorted data. On random data timsort is almost identical to + mergesort. For details of timsort, refer to + `CPython listsort.txt `_. + + Examples -------- >>> a = np.array([[1,4],[3,1]]) @@ -959,7 +967,7 @@ def argsort(a, axis=-1, kind='quicksort', order=None): axis : int or None, optional Axis along which to sort. The default is -1 (the last axis). If None, the flattened array is used. - kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + kind : {'quicksort', 'mergesort', 'heapsort', 'timsort', 'stable'}, optional Sorting algorithm. order : str or list of str, optional When `a` is an array with fields defined, this argument specifies -- cgit v1.2.1 From 317d13bf31798448588c670e6ce175f0abf15dff Mon Sep 17 00:00:00 2001 From: wtli Date: Wed, 30 Jan 2019 10:34:40 +0800 Subject: DOC: update docstring of timsort --- numpy/core/fromnumeric.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 7865dbf64..798a71395 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -895,13 +895,13 @@ def sort(a, axis=-1, kind='quicksort', order=None): worst case O(n*log(n)). 'stable' automatically choses the best stable sorting algorithm - for the data type being sorted. It is currently mapped to - merge sort. + for the data type being sorted. It is currently mapped to timsort. .. versionadded:: 1.17.0 Timsort is added for better performance on already or nearly sorted data. On random data timsort is almost identical to - mergesort. For details of timsort, refer to + mergesort. It is now used for stable sort while quicksort is still the + default sort if none is chosen. For details of timsort, refer to `CPython listsort.txt `_. -- cgit v1.2.1 From 1be850b0782a1dcbb3da22fb9d5c74c3ce367936 Mon Sep 17 00:00:00 2001 From: Dominic Jack Date: Wed, 30 Jan 2019 19:36:50 +1000 Subject: BUG: squeeze corner case --- numpy/core/fromnumeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index d94372986..7b179cf31 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1385,7 +1385,7 @@ def squeeze(a, axis=None): try: squeeze = a.squeeze except AttributeError: - return _wrapit(a, 'squeeze') + return _wrapit(a, 'squeeze', axis=axis) if axis is None: return squeeze() else: -- cgit v1.2.1 From 316c5fe84b906a275fb4dffc0a024b7328bf72b0 Mon Sep 17 00:00:00 2001 From: "Jan S. (Milania1)" Date: Mon, 4 Feb 2019 12:20:02 +0100 Subject: DOC: fix documentation bug in np.argsort and extend examples --- numpy/core/fromnumeric.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 271228b9e..f336ae248 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -979,10 +979,10 @@ def argsort(a, axis=-1, kind='quicksort', order=None): Returns ------- index_array : ndarray, int - Array of indices that sort `a` along the specified axis. + Array of indices that sort `a` along the specified `axis`. If `a` is one-dimensional, ``a[index_array]`` yields a sorted `a`. - More generally, ``np.take_along_axis(a, index_array, axis=a)`` always - yields the sorted `a`, irrespective of dimensionality. + More generally, ``np.take_along_axis(a, index_array, axis=axis)`` + always yields the sorted `a`, irrespective of dimensionality. See Also -------- @@ -1013,13 +1013,21 @@ def argsort(a, axis=-1, kind='quicksort', order=None): array([[0, 3], [2, 2]]) - >>> np.argsort(x, axis=0) # sorts along first axis (down) + >>> ind = np.argsort(x, axis=0) # sorts along first axis (down) + >>> ind array([[0, 1], [1, 0]]) + >>> np.take_along_axis(x, ind, axis=0) # same as np.sort(x, axis=0) + array([[0, 2], + [2, 3]]) - >>> np.argsort(x, axis=1) # sorts along last axis (across) + >>> ind = np.argsort(x, axis=1) # sorts along last axis (across) + >>> ind array([[0, 1], [0, 1]]) + >>> np.take_along_axis(x, ind, axis=1) # same as np.sort(x, axis=1) + array([[0, 3], + [2, 2]]) Indices of the sorted elements of a N-dimensional array: -- cgit v1.2.1 From d3eb626ef41e1302631b5154037567b9cc02630d Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Wed, 6 Feb 2019 19:01:59 -0700 Subject: BUG: Add timsort without breaking the API. In order to maintain forward compatibility it is necessary to keep the size of PyArray_ArrFuncs struct fixed. The usual trick of adding new elements to the end of the structure is not available in this case because the struct may be instanciated by user types and we have no way to know whether the new or old struct is in play. The solution adopted here is the reuse the (a)mergesort slots for stable sorts of all kinds, with the actual kind set when the struct is initialized. The '(a)mergesort' option thus becomes an alias for 'stable', but we keep it for backwards compatibility. --- numpy/core/fromnumeric.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index f336ae248..acfe92a63 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -828,8 +828,16 @@ def sort(a, axis=-1, kind='quicksort', order=None): axis : int or None, optional Axis along which to sort. If None, the array is flattened before sorting. The default is -1, which sorts along the last axis. - kind : {'quicksort', 'mergesort', 'heapsort', 'timsort', 'stable'}, optional - Sorting algorithm. Default is 'quicksort'. + kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + Sorting algorithm. The default is 'quicksort'. Note that both 'stable' + and 'mergesort' use timsort under the covers and, in general, the + actual implementation will vary with datatype. The 'mergesort' option + is retained for backwards compatibility. + + .. versionchanged:: 1.17.0. + The 'stable' option was added together with stable sorting + algorithms other than 'mergesort'. + order : str or list of str, optional When `a` is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can @@ -855,18 +863,22 @@ def sort(a, axis=-1, kind='quicksort', order=None): The various sorting algorithms are characterized by their average speed, worst case performance, work space size, and whether they are stable. A stable sort keeps items with the same key in the same relative - order. The four available algorithms have the following + order. The four algorithms implemented in NumPy have the following properties: =========== ======= ============= ============ ======== kind speed worst case work space stable =========== ======= ============= ============ ======== 'quicksort' 1 O(n^2) 0 no - 'mergesort' 2 O(n*log(n)) ~n/2 yes 'heapsort' 3 O(n*log(n)) 0 no + 'mergesort' 2 O(n*log(n)) ~n/2 yes 'timsort' 2 O(n*log(n)) ~n/2 yes =========== ======= ============= ============ ======== + .. note:: The datatype determines which of 'mergesort' or 'timsort' + is actually used, even if 'mergesort' is specified. User selection + at a finer scale is not currently available. + All the sort algorithms make temporary copies of the data when sorting along any but the last axis. Consequently, sorting along the last axis is faster and uses less space than sorting along @@ -895,7 +907,10 @@ def sort(a, axis=-1, kind='quicksort', order=None): worst case O(n*log(n)). 'stable' automatically choses the best stable sorting algorithm - for the data type being sorted. It is currently mapped to timsort. + for the data type being sorted. It, along with 'mergesort' is + currently mapped to timsort. API forward compatibility currently limits the + ability to select the implementation and it is hardwired for the different + data types. .. versionadded:: 1.17.0 Timsort is added for better performance on already or nearly @@ -967,8 +982,16 @@ def argsort(a, axis=-1, kind='quicksort', order=None): axis : int or None, optional Axis along which to sort. The default is -1 (the last axis). If None, the flattened array is used. - kind : {'quicksort', 'mergesort', 'heapsort', 'timsort', 'stable'}, optional - Sorting algorithm. + kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + Sorting algorithm. The default is 'quicksort'. Note that both 'stable' + and 'mergesort' use timsort under the covers and, in general, the + actual implementation will vary with datatype. The 'mergesort' option + is retained for backwards compatibility. + + .. versionchanged:: 1.17.0. + The 'stable' option was added together with stable sorting + algorithms other than 'mergesort'. + order : str or list of str, optional When `a` is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can -- cgit v1.2.1 From 107e45b82021ba04f651f0ef89aa2f419d404d64 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Fri, 8 Feb 2019 17:45:28 -0700 Subject: DOC: Update sorting documention. Update the sorting documentation to reflect the reality that 'mergesort' and 'stable' are aliases and may refer to any of several stable sorting algorithms depending on data type. [ci skip] --- numpy/core/fromnumeric.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index acfe92a63..cdb6c4bed 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -831,12 +831,11 @@ def sort(a, axis=-1, kind='quicksort', order=None): kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional Sorting algorithm. The default is 'quicksort'. Note that both 'stable' and 'mergesort' use timsort under the covers and, in general, the - actual implementation will vary with datatype. The 'mergesort' option + actual implementation will vary with data type. The 'mergesort' option is retained for backwards compatibility. - .. versionchanged:: 1.17.0. - The 'stable' option was added together with stable sorting - algorithms other than 'mergesort'. + .. versionchanged:: 1.15.0. + The 'stable' option was added. order : str or list of str, optional When `a` is an array with fields defined, this argument specifies @@ -985,12 +984,12 @@ def argsort(a, axis=-1, kind='quicksort', order=None): kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional Sorting algorithm. The default is 'quicksort'. Note that both 'stable' and 'mergesort' use timsort under the covers and, in general, the - actual implementation will vary with datatype. The 'mergesort' option + actual implementation will vary with data type. The 'mergesort' option is retained for backwards compatibility. - .. versionchanged:: 1.17.0. - The 'stable' option was added together with stable sorting - algorithms other than 'mergesort'. + .. versionchanged:: 1.15.0. + The 'stable' option was added. + order : str or list of str, optional When `a` is an array with fields defined, this argument specifies -- cgit v1.2.1 From 62433284d65a3629a199958da2df3a807c60fab4 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 20 Feb 2019 23:46:20 +0200 Subject: DOC: reduce warnings when building, reword, tweak doc building --- numpy/core/fromnumeric.py | 1 + 1 file changed, 1 insertion(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index cdb6c4bed..04b1e9fae 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -912,6 +912,7 @@ def sort(a, axis=-1, kind='quicksort', order=None): data types. .. versionadded:: 1.17.0 + Timsort is added for better performance on already or nearly sorted data. On random data timsort is almost identical to mergesort. It is now used for stable sort while quicksort is still the -- cgit v1.2.1 From 352b7871a072a51f32bcb6bc1541cabbc447d5c4 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 12 Mar 2019 17:45:29 +0100 Subject: MAINT: Prevent traceback chaining in _wrapfunc. The traceback of `np.reshape([1, 2, 3], 2)` is shortened from ``` Traceback (most recent call last): File ".../numpy/core/fromnumeric.py", line 56, in _wrapfunc return getattr(obj, method)(*args, **kwds) AttributeError: 'list' object has no attribute 'reshape' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 1, in File ".../numpy/core/overrides.py", line 151, in public_api implementation, public_api, relevant_args, args, kwargs) File ".../numpy/core/fromnumeric.py", line 296, in reshape return _wrapfunc(a, 'reshape', newshape, order=order) File ".../numpy/core/fromnumeric.py", line 66, in _wrapfunc return _wrapit(obj, method, *args, **kwds) File ".../numpy/core/fromnumeric.py", line 46, in _wrapit result = getattr(asarray(obj), method)(*args, **kwds) ValueError: cannot reshape array of size 3 into shape (2,) ``` to ``` Traceback (most recent call last): File "", line 1, in File ".../numpy/core/overrides.py", line 151, in public_api implementation, public_api, relevant_args, args, kwargs) File ".../numpy/core/fromnumeric.py", line 300, in reshape return _wrapfunc(a, 'reshape', newshape, order=order) File ".../numpy/core/fromnumeric.py", line 70, in _wrapfunc return _wrapit(obj, method, *args, **kwds) File ".../numpy/core/fromnumeric.py", line 46, in _wrapit result = getattr(asarray(obj), method)(*args, **kwds) ValueError: cannot reshape array of size 3 into shape (2,) ``` (The chained exception is really just an implementation detail.) --- numpy/core/fromnumeric.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 04b1e9fae..760577890 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -52,17 +52,20 @@ def _wrapit(obj, method, *args, **kwds): def _wrapfunc(obj, method, *args, **kwds): - try: - return getattr(obj, method)(*args, **kwds) - - # An AttributeError occurs if the object does not have - # such a method in its class. + bound = getattr(obj, method, None) + if bound is None: + return _wrapit(obj, method, *args, **kwds) - # A TypeError occurs if the object does have such a method - # in its class, but its signature is not identical to that - # of NumPy's. This situation has occurred in the case of - # a downstream library like 'pandas'. - except (AttributeError, TypeError): + try: + return bound(*args, **kwds) + except TypeError: + # A TypeError occurs if the object does have such a method in its + # class, but its signature is not identical to that of NumPy's. This + # situation has occurred in the case of a downstream library like + # 'pandas'. + # + # Call _wrapit from within the except clause to ensure a potential + # exception has a traceback chain. return _wrapit(obj, method, *args, **kwds) -- cgit v1.2.1 From e6147b9bf580361f2f74ac72003f81e957587528 Mon Sep 17 00:00:00 2001 From: Allan Haldane Date: Wed, 27 Mar 2019 09:30:04 -0400 Subject: MAINT: add overlap checks to choose, take, put, putmask (#13182) Fixes #9293, #6272 --- numpy/core/fromnumeric.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 760577890..cb10c3947 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -130,7 +130,8 @@ def take(a, indices, axis=None, out=None, mode='raise'): input array is used. out : ndarray, optional (Ni..., Nj..., Nk...) If provided, the result will be placed in this array. It should - be of the appropriate shape and dtype. + be of the appropriate shape and dtype. Note that `out` is always + buffered if `mode='raise'`; use other modes for better performance. mode : {'raise', 'wrap', 'clip'}, optional Specifies how out-of-bounds indices will behave. @@ -355,7 +356,8 @@ def choose(a, choices, out=None, mode='raise'): ``choices.shape[0]``) is taken as defining the "sequence". out : array, optional If provided, the result will be inserted into this array. It should - be of the appropriate shape and dtype. + be of the appropriate shape and dtype. Note that `out` is always + buffered if `mode='raise'`; use other modes for better performance. mode : {'raise' (default), 'wrap', 'clip'}, optional Specifies how indices outside `[0, n-1]` will be treated: @@ -512,7 +514,8 @@ def put(a, ind, v, mode='raise'): 'clip' mode means that all indices that are too large are replaced by the index that addresses the last element along that axis. Note - that this disables indexing with negative numbers. + that this disables indexing with negative numbers. In 'raise' mode, + if an exception occurs the target array may still be modified. See Also -------- -- cgit v1.2.1 From e44713c51421bcf53e4babcc97574b9143bdd7a0 Mon Sep 17 00:00:00 2001 From: Ander Ustarroz Date: Fri, 12 Apr 2019 17:41:05 +0200 Subject: DOC: Added anti-diagonal examples to np.diagonal and np.fill_diagonal --- numpy/core/fromnumeric.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index cb10c3947..0e89277d8 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1531,9 +1531,9 @@ def diagonal(a, offset=0, axis1=0, axis2=1): [2, 3]], [[4, 5], [6, 7]]]) - >>> a.diagonal(0, # Main diagonals of two arrays created by skipping - ... 0, # across the outer(left)-most axis last and - ... 1) # the "middle" (row) axis first. + >>> a.diagonal(0, # Main diagonals of two arrays created by skipping + ... 0, # across the outer(left)-most axis last and + ... 1) # the "middle" (row) axis first. array([[0, 6], [1, 7]]) @@ -1541,13 +1541,28 @@ def diagonal(a, offset=0, axis1=0, axis2=1): corresponds to fixing the right-most (column) axis, and that the diagonals are "packed" in rows. - >>> a[:,:,0] # main diagonal is [0 6] + >>> a[:,:,0] # main diagonal is [0 6] array([[0, 2], [4, 6]]) - >>> a[:,:,1] # main diagonal is [1 7] + >>> a[:,:,1] # main diagonal is [1 7] array([[1, 3], [5, 7]]) + The anti-diagonal can be obtained by reversing the order of elements + using either `numpy.flipud` or `numpy.fliplr`. + + >>> a = np.arange(9).reshape(3, 3) + >>> a + array([[0, 1, 2], + [3, 4, 5], + [6, 7, 8]]) + >>> np.fliplr(a).diagonal() # Horizontal flip + array([2, 4, 6]) + >>> np.flipud(a).diagonal() # Vertical flip + array([6, 4, 2]) + + Note that the order in which the diagonal is retrieved varies depending + on the flip function. """ if isinstance(a, np.matrix): # Make diagonal of matrix 1-D to preserve backward compatibility. -- cgit v1.2.1 From 82641c61b1a2d6d1b8cccce5a65f4215c94b99b2 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 13 Apr 2019 17:10:35 -0700 Subject: MAINT: Move asarray helpers into their own module This is a direct move, with some tweaks to imports. This breaks a cyclic imports between `core.numeric` and `core.fromnumeric`. This doesn't affect the value of `np.core.numeric.__all__` which keeps code doing `from numpy.core.numeric import *` working. --- numpy/core/fromnumeric.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index cb10c3947..b4e5965d2 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -13,7 +13,8 @@ from . import multiarray as mu from . import overrides from . import umath as um from . import numerictypes as nt -from .numeric import asarray, array, asanyarray, concatenate +from ._asarray import asarray, array, asanyarray +from .multiarray import concatenate from . import _methods _dt_ = nt.sctype2char -- cgit v1.2.1 From 524abf2f43b0f6d5baaec14c5e1a5feb53610f73 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sun, 14 Apr 2019 21:59:26 +0200 Subject: DOC: fix doc formatting issues exposed by numpydoc 0.9.0rc1 --- numpy/core/fromnumeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index cb10c3947..2bd399c23 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -3390,7 +3390,7 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): See Also -------- - std , mean, nanmean, nanstd, nanvar + std, mean, nanmean, nanstd, nanvar numpy.doc.ufuncs : Section "Output arguments" Notes -- cgit v1.2.1 From 12fb1015511ac3804d0785bb0d1fe539385548ad Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Fri, 10 May 2019 19:14:35 -0700 Subject: ENH: Radix sort --- numpy/core/fromnumeric.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index b4d721940..7024ac237 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -824,7 +824,7 @@ def _sort_dispatcher(a, axis=None, kind=None, order=None): @array_function_dispatch(_sort_dispatcher) -def sort(a, axis=-1, kind='quicksort', order=None): +def sort(a, axis=-1, kind=None, order=None): """ Return a sorted copy of an array. @@ -837,8 +837,8 @@ def sort(a, axis=-1, kind='quicksort', order=None): sorting. The default is -1, which sorts along the last axis. kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional Sorting algorithm. The default is 'quicksort'. Note that both 'stable' - and 'mergesort' use timsort under the covers and, in general, the - actual implementation will vary with data type. The 'mergesort' option + and 'mergesort' use timsort or radix sort under the covers and, in general, + the actual implementation will vary with data type. The 'mergesort' option is retained for backwards compatibility. .. versionchanged:: 1.15.0. @@ -914,7 +914,8 @@ def sort(a, axis=-1, kind='quicksort', order=None): 'stable' automatically choses the best stable sorting algorithm for the data type being sorted. It, along with 'mergesort' is - currently mapped to timsort. API forward compatibility currently limits the + currently mapped to timsort or radix sort depending on the + data type. API forward compatibility currently limits the ability to select the implementation and it is hardwired for the different data types. @@ -925,7 +926,8 @@ def sort(a, axis=-1, kind='quicksort', order=None): mergesort. It is now used for stable sort while quicksort is still the default sort if none is chosen. For details of timsort, refer to `CPython listsort.txt `_. - + 'mergesort' and 'stable' are mapped to radix sort for integer data types. Radix sort is an + O(n) sort instead of O(n log n). Examples -------- @@ -974,7 +976,7 @@ def _argsort_dispatcher(a, axis=None, kind=None, order=None): @array_function_dispatch(_argsort_dispatcher) -def argsort(a, axis=-1, kind='quicksort', order=None): +def argsort(a, axis=-1, kind=None, order=None): """ Returns the indices that would sort an array. @@ -997,8 +999,6 @@ def argsort(a, axis=-1, kind='quicksort', order=None): .. versionchanged:: 1.15.0. The 'stable' option was added. - - order : str or list of str, optional When `a` is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can -- cgit v1.2.1 From dfe7b9db2350505903ba19867bf27dabda2bff71 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sun, 9 Dec 2018 01:08:33 -0800 Subject: ENH/DEP: Use a ufunc under the hood for ndarray.clip This includes: * The addition of 3-input PyObject inner loop * The removal of `->f->fastclip` for builtin types, which now use ufuncs instead * A deprecation in `PyArray_Clip` for third-party types that still use `->f->fastclip` * A deprecation of the unusual casting behavior of `clip` * A deprecation of the broken `nan`-behavior of `clip`, which was previously dependent on dimensionality and byte-order. --- numpy/core/fromnumeric.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 7024ac237..814ade64e 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1961,12 +1961,12 @@ def compress(condition, a, axis=None, out=None): return _wrapfunc(a, 'compress', condition, axis=axis, out=out) -def _clip_dispatcher(a, a_min, a_max, out=None): +def _clip_dispatcher(a, a_min, a_max, out=None, **kwargs): return (a, a_min, a_max) @array_function_dispatch(_clip_dispatcher) -def clip(a, a_min, a_max, out=None): +def clip(a, a_min, a_max, out=None, **kwargs): """ Clip (limit) the values in an array. @@ -1992,6 +1992,11 @@ def clip(a, a_min, a_max, out=None): The results will be placed in this array. It may be the input array for in-place clipping. `out` must be of the right shape to hold the output. Its type is preserved. + **kwargs + For other keyword-only arguments, see the + :ref:`ufunc docs `. + + .. versionadded:: 1.17.0 Returns ------- @@ -2020,7 +2025,7 @@ def clip(a, a_min, a_max, out=None): array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - return _wrapfunc(a, 'clip', a_min, a_max, out=out) + return _wrapfunc(a, 'clip', a_min, a_max, out=out, **kwargs) def _sum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, -- cgit v1.2.1 From 6492f632a92439c82c74efa6753e10ce9360c6ba Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Mon, 4 Mar 2019 19:27:47 -0800 Subject: MAINT: address reviewer comments * Unit test for object clip issue * parametrized test_simple_int32_inout() to additionally handle scenario where "unsafe" casting is explicitly passed through, as requested by reviewer * add a requested comment related to possibility of future nan check optimization for `@name@_clip` * add a unit test to cover the case where np.clip() is called with None for both max and min * add a unit test for the case where out is None and casting is specified as an invalid value, to flush through code path in TestClip.fastclip * add unit test + doc update for expected behavior when amin > amax * add unit test + patch for bug in npy_ObjectClip; its operations and operands were wrong; the unit test case is based on a scenario probed by the hypothesis library * add unit test for error in timedelta64 MAX function for clip handling * add unit test for a pathological case where np.ones(10) is clipped with amin=1, amax=0 --- numpy/core/fromnumeric.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 814ade64e..58da8a54b 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1975,6 +1975,9 @@ def clip(a, a_min, a_max, out=None, **kwargs): is specified, values smaller than 0 become 0, and values larger than 1 become 1. + Equivalent to but faster than ``np.maximum(a_min, np.minimum(a, a_max))``. + No check is performed to ensure ``a_min < a_max``. + Parameters ---------- a : array_like -- cgit v1.2.1 From 0ca5969ae7dcd1770f117d8c8782b7c4ec4e5ca4 Mon Sep 17 00:00:00 2001 From: John Belmonte Date: Thu, 16 May 2019 11:37:53 +0900 Subject: searchsorted: remove performance claim Fixes #13566 --- numpy/core/fromnumeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 58da8a54b..a5d27a008 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1279,7 +1279,7 @@ def searchsorted(a, v, side='left', sorter=None): As of NumPy 1.4.0 `searchsorted` works with real/complex arrays containing `nan` values. The enhanced sort order is documented in `sort`. - This function is a faster version of the builtin python `bisect.bisect_left` + This function is a version of the builtin python `bisect.bisect_left` (``side='left'``) and `bisect.bisect_right` (``side='right'``) functions, which is also vectorized in the `v` argument. -- cgit v1.2.1 From f9c1502e7ace9b48f0256a77c560aae43763a1f2 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Mon, 20 May 2019 09:37:18 -0700 Subject: BUG: Increment stacklevel for warnings to account for NEP-18 overrides (#13589) * Increment stacklevel for warnings to account for NEP-18 overrides For NumPy functions that make use of `__array_function__`, the appropriate the stack level for warnings should generally be increased by 1 to account for the override function defined in numpy.core.overrides. Fixes GH-13329 * Update numpy/lib/type_check.py Co-Authored-By: Sebastian Berg --- numpy/core/fromnumeric.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 58da8a54b..cbbee463a 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2145,7 +2145,7 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, warnings.warn( "Calling np.sum(generator) is deprecated, and in the future will give a different result. " "Use np.sum(np.fromiter(generator)) or the python sum builtin instead.", - DeprecationWarning, stacklevel=2) + DeprecationWarning, stacklevel=3) res = _sum_(a) if out is not None: @@ -3569,5 +3569,5 @@ def rank(a): warnings.warn( "`rank` is deprecated; use the `ndim` attribute or function instead. " "To find the rank of a matrix see `numpy.linalg.matrix_rank`.", - VisibleDeprecationWarning, stacklevel=2) + VisibleDeprecationWarning, stacklevel=3) return ndim(a) -- cgit v1.2.1 From 966ccea02bd3f9f8fa7fffb8c2903ff2daf83b58 Mon Sep 17 00:00:00 2001 From: John Belmonte Date: Wed, 22 May 2019 21:21:43 +0900 Subject: change wording --- numpy/core/fromnumeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index a5d27a008..b81a4fa05 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1279,7 +1279,7 @@ def searchsorted(a, v, side='left', sorter=None): As of NumPy 1.4.0 `searchsorted` works with real/complex arrays containing `nan` values. The enhanced sort order is documented in `sort`. - This function is a version of the builtin python `bisect.bisect_left` + This function uses the same algorithm as the builtin python `bisect.bisect_left` (``side='left'``) and `bisect.bisect_right` (``side='right'``) functions, which is also vectorized in the `v` argument. -- cgit v1.2.1 From 1f427353554e6403f87c01f81b6e414427faa5f0 Mon Sep 17 00:00:00 2001 From: Abhinav Sagar <40603139+abhinavsagar@users.noreply.github.com> Date: Wed, 29 May 2019 10:43:35 +0530 Subject: DOC: Add note to ``nonzero`` docstring. (#13551) * Added NOTE in numpy\core\fromnumeric.py --- numpy/core/fromnumeric.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 202802e2c..af2a5298d 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1795,6 +1795,11 @@ def nonzero(a): Equivalent ndarray method. count_nonzero : Counts the number of non-zero elements in the input array. + + Notes + ----- + To obtain the non-zero values, it is recommended to use ``x[x.astype(bool)]`` + which will correctly handle 0-d arrays. Examples -------- -- cgit v1.2.1 From dcf9d9628eb50d275a6d42a6ed2cfdd25949ef57 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Fri, 7 Jun 2019 11:18:16 +0300 Subject: DOC: emphasize that nonzero is a bad idea on 0d arrays Also indicate that the current behavior in this case is deprecated. This also removes the advice to use `a[nonzero(a)]` or `transpose(nonzero(a))`, for which there are better spellings. --- numpy/core/fromnumeric.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index af2a5298d..d78cdf365 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1764,17 +1764,17 @@ def nonzero(a): Returns a tuple of arrays, one for each dimension of `a`, containing the indices of the non-zero elements in that dimension. The values in `a` are always tested and returned in - row-major, C-style order. The corresponding non-zero - values can be obtained with:: + row-major, C-style order. - a[nonzero(a)] + To group the indices by element, rather than dimension, use `argwhere`, + which returns a row for each non-zero element. - To group the indices by element, rather than dimension, use:: - - transpose(nonzero(a)) + .. note:: + When called on a zero-d array or scalar, ``nonzero(a)`` is treated + as ``nonzero(atleast1d(a))``. - The result of this is always a 2-D array, with a row for - each non-zero element. + ..deprecated:: 1.17.0 + Use `atleast1d` explicitly if this behavior is deliberate. Parameters ---------- @@ -1795,11 +1795,12 @@ def nonzero(a): Equivalent ndarray method. count_nonzero : Counts the number of non-zero elements in the input array. - + Notes ----- - To obtain the non-zero values, it is recommended to use ``x[x.astype(bool)]`` - which will correctly handle 0-d arrays. + While the nonzero values can be obtained with ``a[nonzero(a)]``, it is + recommended to use ``x[x.astype(bool)]`` or ``x[x != 0]`` instead, which + will correctly handle 0-d arrays. Examples -------- -- cgit v1.2.1 From 871ed9b188da73bfed6386530e579e3287e9b3ed Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Tue, 11 Jun 2019 00:55:45 -0500 Subject: DOC: Mention and try to explain pairwise summation in sum (#13737) * DOC: Mention and try to explain pairwise summation in sum Note that this behaviour is of course inherited into `np.add.reduce` and many other reductions such as `mean` or users of this reduction, such as `cov`. This is ignored here. --- numpy/core/fromnumeric.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index af2a5298d..f262f8552 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2104,6 +2104,8 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, -------- ndarray.sum : Equivalent method. + add.reduce : Equivalent functionality of `add`. + cumsum : Cumulative sum of array elements. trapz : Integration of array values using the composite trapezoidal rule. @@ -2120,6 +2122,23 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, >>> np.sum([]) 0.0 + For floating point numbers the numerical precision of sum (and + ``np.add.reduce``) is in general limited by directly adding each number + individually to the result causing rounding errors in every step. + However, often numpy will use a numerically better approach (partial + pairwise summation) leading to improved precision in many use-cases. + This improved precision is always provided when no ``axis`` is given. + When ``axis`` is given, it will depend on which axis is summed. + Technically, to provide the best speed possible, the improved precision + is only used when the summation is along the fast axis in memory. + Note that the exact precision may vary depending on other parameters. + In contrast to NumPy, Python's ``math.fsum`` function uses a slower but + more precise approach to summation. + Especially when summing a large number of lower precision floating point + numbers, such as ``float32``, numerical errors can become significant. + In such cases it can be advisable to use `dtype="float64"` to use a higher + precision for the output. + Examples -------- >>> np.sum([0.5, 1.5]) -- cgit v1.2.1