From f2b27fb90809bdf464e66b9f3be8037e9a72c0f7 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 4 Mar 2017 02:39:14 +0000 Subject: DOC: expand_dims and squeeze are inverses [ci skip] --- numpy/core/fromnumeric.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 58f8696d2..ed7c7eb93 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1162,6 +1162,16 @@ def squeeze(a, axis=None): dimensions of length 1 removed. This is always `a` itself or a view into `a`. + Raises + ------ + ValueError + If `axis` is not `None`, and an axis being squeezed is not of length 1 + + See Also + -------- + expand_dims : The inverse operation, adding singleton dimensions + reshape : Insert, remove, and combine dimensions, and resize existing ones + Examples -------- >>> x = np.array([[[0], [1], [2]]]) @@ -1169,7 +1179,13 @@ def squeeze(a, axis=None): (1, 3, 1) >>> np.squeeze(x).shape (3,) - >>> np.squeeze(x, axis=(2,)).shape + >>> np.squeeze(x, axis=0).shape + (3, 1) + >>> np.squeeze(x, axis=1).shape + Traceback (most recent call last): + ... + ValueError: cannot select an axis to squeeze out which has size not equal to one + >>> np.squeeze(x, axis=2).shape (1, 3) """ -- cgit v1.2.1 From 77c875f66d2da61da7cecf40ecc8409a02bfc124 Mon Sep 17 00:00:00 2001 From: jsh9 Date: Thu, 30 Mar 2017 06:49:08 -0700 Subject: DOC: Updated doc of nonzero() to eliminate ambiguity (#8850) --- numpy/core/fromnumeric.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 58f8696d2..973ba7b3a 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1509,13 +1509,12 @@ def nonzero(a): Examples -------- - >>> x = np.eye(3) + >>> x = np.array([[1,0,0], [0,2,0], [1,1,0]]) >>> x - array([[ 1., 0., 0.], - [ 0., 1., 0.], - [ 0., 0., 1.]]) - >>> np.nonzero(x) - (array([0, 1, 2]), array([0, 1, 2])) + array([[1, 0, 0], + [0, 2, 0], + [1, 1, 0]]) + >>> (array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64)) >>> x[np.nonzero(x)] array([ 1., 1., 1.]) -- cgit v1.2.1 From 58c604c1aa765d37f0d0324efb1852ddf4d9d9ef Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 30 Mar 2017 14:55:30 +0100 Subject: DOC: Replace line that was errantly removed in #8850 Apologies for the bad merge here [ci skip] --- 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 973ba7b3a..4309277ad 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1514,7 +1514,8 @@ def nonzero(a): array([[1, 0, 0], [0, 2, 0], [1, 1, 0]]) - >>> (array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64)) + >>> np.nonzero(x) + (array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64)) >>> x[np.nonzero(x)] array([ 1., 1., 1.]) -- cgit v1.2.1 From 1b3e6f1d8dad0b3b7d8a0891dcb2050cdc023075 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 1 Jul 2017 11:40:29 +0100 Subject: BUG: np.resize discards empty shapes --- numpy/core/fromnumeric.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index a8c2fd2fb..4922fc3e4 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1120,18 +1120,16 @@ def resize(a, new_shape): new_shape = (new_shape,) a = ravel(a) Na = len(a) - if not Na: - return mu.zeros(new_shape, a.dtype) total_size = um.multiply.reduce(new_shape) + if Na == 0 or total_size == 0: + return mu.zeros(new_shape, a.dtype) + n_copies = int(total_size / Na) extra = total_size % Na - if total_size == 0: - return a[:0] - if extra != 0: - n_copies = n_copies+1 - extra = Na-extra + n_copies = n_copies + 1 + extra = Na - extra a = concatenate((a,)*n_copies) if extra > 0: -- cgit v1.2.1 From 2b781f8967488dc007f8f0a1e6a7f49208788d12 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 1 Aug 2017 20:29:36 +0000 Subject: MAINT/DOC: Use builtin when np.{x} is builtins.{x}. This is the case for x in {int, bool, str, float, complex, object}. Using the np.{x} version is deceptive as it suggests that there is a difference. This change doesn't affect any external behaviour. The `long` type is missing in python 3, so np.long is still useful --- 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 4922fc3e4..338248ce3 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2246,7 +2246,7 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue): >>> np.amax(a, axis=1) # Maxima along the second axis array([1, 3]) - >>> b = np.arange(5, dtype=np.float) + >>> b = np.arange(5, dtype=float) >>> b[2] = np.NaN >>> np.amax(b) nan @@ -2347,7 +2347,7 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue): >>> np.amin(a, axis=1) # Minima along the second axis array([0, 2]) - >>> b = np.arange(5, dtype=np.float) + >>> b = np.arange(5, dtype=float) >>> b[2] = np.NaN >>> np.amin(b) nan @@ -2497,7 +2497,7 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): is the default platform integer: >>> x = np.array([1, 2, 3], dtype=np.int8) - >>> np.prod(x).dtype == np.int + >>> np.prod(x).dtype == int True """ -- cgit v1.2.1 From 6aed49135b26fe23620b15cab6c3b99c56545867 Mon Sep 17 00:00:00 2001 From: Brandon Carter Date: Mon, 21 Aug 2017 16:24:24 -0700 Subject: update example in np.nonzero docstring --- numpy/core/fromnumeric.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 338248ce3..10b20c0b1 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1529,14 +1529,15 @@ def nonzero(a): [0, 2, 0], [1, 1, 0]]) >>> np.nonzero(x) - (array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64)) + (array([0, 1, 2, 2]), array([0, 1, 0, 1])) >>> x[np.nonzero(x)] - array([ 1., 1., 1.]) + array([1, 2, 1, 1]) >>> np.transpose(np.nonzero(x)) array([[0, 0], [1, 1], - [2, 2]]) + [2, 0], + [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 -- cgit v1.2.1 From be08980377cf2cd0c136e32eb0c644d392e5c7be Mon Sep 17 00:00:00 2001 From: Srinivas Reddy Thatiparthy Date: Sat, 26 Aug 2017 19:59:24 +0530 Subject: MAINT: remove try..except clause. - Generator type has been added to types module in 2.2 we do not need to catch AttributeError --- numpy/core/fromnumeric.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 10b20c0b1..6f7c45859 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -28,12 +28,7 @@ __all__ = [ 'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var', ] - -try: - _gentype = types.GeneratorType -except AttributeError: - _gentype = type(None) - +_gentype = types.GeneratorType # save away Python sum _sum_ = sum -- cgit v1.2.1 From f01d1a6a5c381a4406d92db2993bf01b8e849b8c Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Wed, 27 Sep 2017 01:37:34 -0700 Subject: BUG: np.ma.trace gives the wrong result on ND arrays Fixes #5560 --- numpy/core/fromnumeric.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 6f7c45859..a94be7b4d 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1245,13 +1245,13 @@ def diagonal(a, offset=0, axis1=0, axis2=1): Returns ------- array_of_diagonals : ndarray - If `a` is 2-D and not a matrix, a 1-D array of the same type as `a` - containing the diagonal is returned. If `a` is a matrix, a 1-D + If `a` is 2-D and not a `matrix`, a 1-D array of the same type as `a` + containing the diagonal is returned. If `a` is a `matrix`, a 1-D array containing the diagonal is returned in order to maintain - backward compatibility. If the dimension of `a` is greater than - two, then an array of diagonals is returned, "packed" from - left-most dimension to right-most (e.g., if `a` is 3-D, then the - diagonals are "packed" along rows). + 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. Raises ------ -- cgit v1.2.1 From a94c15fcd6456c6df3a060a5fdae797649eb787e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lie=20Gouzien?= Date: Thu, 29 Jun 2017 23:54:11 +0200 Subject: DOC: Add examples for np.arg[min|max|sort] Show how to retrieve indices for d-dim arrays. [ci skip] --- numpy/core/fromnumeric.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index a94be7b4d..78b156f21 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -885,6 +885,14 @@ def argsort(a, axis=-1, kind='quicksort', order=None): array([[0, 1], [0, 1]]) + Indices of the sorted elements of a N-dimensional array: + >>> np.unravel_index(np.argsort(x, axis=None), x.shape) + (array([0, 1, 1, 0]), array([0, 0, 1, 1])) + >>> from np.testing import assert_equal + >>> assert_equal(x[(array([0, 1, 1, 0]), array([0, 0, 1, 1]))], np.sort(x, axis=None)) + >>> list(zip(*np.unravel_index(np.argsort(x, axis=None), x.shape))) + [(0, 0), (1, 0), (1, 1), (0, 1)] + Sorting with keys: >>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '>> np.argmax(a, axis=1) array([2, 2]) + Indices of the maximal elements of a N-dimensional array: + >>> np.unravel_index(np.argmax(a, axis=None), a.shape) + (1, 2) + >>> np.testing.assert_equal(a[(1, 2)], np.max(a)) + >>> b = np.arange(6) >>> b[1] = 5 >>> b @@ -1003,6 +1016,11 @@ def argmin(a, axis=None, out=None): >>> np.argmin(a, axis=1) array([0, 0]) + Indices of the minimum elements of a N-dimensional array: + >>> np.unravel_index(np.argmin(a, axis=None), a.shape) + (0, 0) + >>> np.testing.assert_equal(a[(0, 0)], np.min(a)) + >>> b = np.arange(6) >>> b[4] = 0 >>> b -- cgit v1.2.1 From c730ffd2044fb2815c7b26c9ca9d6fea9f3d3091 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Thu, 5 Oct 2017 11:46:42 -0600 Subject: DOC: Redo some examples of np.arg(sort|max|min) [ci skip] --- numpy/core/fromnumeric.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 78b156f21..ebeea6319 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -877,21 +877,21 @@ def argsort(a, axis=-1, kind='quicksort', order=None): array([[0, 3], [2, 2]]) - >>> np.argsort(x, axis=0) + >>> np.argsort(x, axis=0) # sorts along first axis (down) array([[0, 1], [1, 0]]) - >>> np.argsort(x, axis=1) + >>> np.argsort(x, axis=1) # sorts along last axis (across) array([[0, 1], [0, 1]]) Indices of the sorted elements of a N-dimensional array: - >>> np.unravel_index(np.argsort(x, axis=None), x.shape) + + >>> ind = np.unravel_index(np.argsort(x, axis=None), x.shape) + >>> ind (array([0, 1, 1, 0]), array([0, 0, 1, 1])) - >>> from np.testing import assert_equal - >>> assert_equal(x[(array([0, 1, 1, 0]), array([0, 0, 1, 1]))], np.sort(x, axis=None)) - >>> list(zip(*np.unravel_index(np.argsort(x, axis=None), x.shape))) - [(0, 0), (1, 0), (1, 1), (0, 1)] + >>> x[ind] # same as np.sort(x, axis=None) + array([0, 2, 2, 3]) Sorting with keys: @@ -955,16 +955,19 @@ def argmax(a, axis=None, out=None): >>> np.argmax(a, axis=1) array([2, 2]) - Indices of the maximal elements of a N-dimensional array: - >>> np.unravel_index(np.argmax(a, axis=None), a.shape) + Indexes of the maximal elements of a N-dimensional array: + + >>> ind = np.unravel_index(np.argmax(a, axis=None), a.shape) + >>> ind (1, 2) - >>> np.testing.assert_equal(a[(1, 2)], np.max(a)) + >>> a[ind] + 5 >>> b = np.arange(6) >>> b[1] = 5 >>> b array([0, 5, 2, 3, 4, 5]) - >>> np.argmax(b) # Only the first occurrence is returned. + >>> np.argmax(b) # Only the first occurrence is returned. 1 """ @@ -1017,15 +1020,18 @@ def argmin(a, axis=None, out=None): array([0, 0]) Indices of the minimum elements of a N-dimensional array: - >>> np.unravel_index(np.argmin(a, axis=None), a.shape) + + >>> ind = np.unravel_index(np.argmin(a, axis=None), a.shape) + >>> ind (0, 0) - >>> np.testing.assert_equal(a[(0, 0)], np.min(a)) + >>> a[ind] + 0 >>> b = np.arange(6) >>> b[4] = 0 >>> b array([0, 1, 2, 3, 0, 5]) - >>> np.argmin(b) # Only the first occurrence is returned. + >>> np.argmin(b) # Only the first occurrence is returned. 0 """ @@ -2475,7 +2481,7 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): raised on overflow. That means that, on a 32-bit platform: >>> x = np.array([536870910, 536870910, 536870910, 536870910]) - >>> np.prod(x) #random + >>> np.prod(x) # random 16 The product of an empty array is the neutral element 1: -- cgit v1.2.1 From ac6b1a902b99e340cf7eeeeb7392c91e38db9dd8 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 13 Nov 2017 23:45:45 -0800 Subject: ENH: don't show boolean dtype, as it is implied --- numpy/core/fromnumeric.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index ebeea6319..568d39781 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1567,7 +1567,7 @@ def nonzero(a): >>> a > 3 array([[False, False, False], [ True, True, True], - [ True, True, True]], dtype=bool) + [ True, True, True]]) >>> np.nonzero(a > 3) (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) @@ -1962,7 +1962,7 @@ def any(a, axis=None, out=None, keepdims=np._NoValue): True >>> np.any([[True, False], [False, False]], axis=0) - array([ True, False], dtype=bool) + array([ True, False]) >>> np.any([-1, 0, 5]) True @@ -1973,7 +1973,7 @@ def any(a, axis=None, out=None, keepdims=np._NoValue): >>> o=np.array([False]) >>> z=np.any([-1, 4, 5], out=o) >>> z, o - (array([ True], dtype=bool), array([ True], dtype=bool)) + (array([ True]), array([ True])) >>> # Check now that z is a reference to o >>> z is o True @@ -2047,7 +2047,7 @@ def all(a, axis=None, out=None, keepdims=np._NoValue): False >>> np.all([[True,False],[True,True]], axis=0) - array([ True, False], dtype=bool) + array([ True, False]) >>> np.all([-1, 4, 5]) True @@ -2058,7 +2058,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 # doctest: +SKIP - (28293632, 28293632, array([ True], dtype=bool)) + (28293632, 28293632, array([ True])) """ arr = asanyarray(a) -- cgit v1.2.1 From 21ef1383cb4f6e27af188a6da5cdca93cff1bd07 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 28 Feb 2017 14:36:41 +0000 Subject: DOC: describe the expansion of take and apply_along_axis in detail Extracted from gh-8714 [ci-skip] --- numpy/core/fromnumeric.py | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index ebeea6319..a83250e6e 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -66,15 +66,28 @@ def take(a, indices, axis=None, out=None, mode='raise'): """ Take elements from an array along an axis. - This function does the same thing as "fancy" indexing (indexing arrays - using arrays); however, it can be easier to use if you need elements - along a given axis. + When axis is not None, this function does the same thing as "fancy" + indexing (indexing arrays using arrays); however, it can be easier to use + if you need elements along a given axis. A call such as + ``np.take(arr, indices, axis=3)`` is equivalent to + ``arr[:,:,:,indices,...]``. + + Explained without fancy indexing, this is equivalent to the following use + of `ndindex`, which sets each of ``ii``, ``jj``, and ``kk`` to a tuple of + indices:: + + Ni, Nk = a.shape[:axis], a.shape[axis+1:] + Nj = indices.shape + for ii in ndindex(Ni): + for jj in ndindex(Nj): + for kk in ndindex(Nk): + out[ii + jj + kk] = a[ii + (indices[jj],) + kk] Parameters ---------- - a : array_like + a : array_like (Ni..., M, Nk...) The source array. - indices : array_like + indices : array_like (Nj...) The indices of the values to extract. .. versionadded:: 1.8.0 @@ -83,7 +96,7 @@ def take(a, indices, axis=None, out=None, mode='raise'): axis : int, optional The axis over which to select values. By default, the flattened input array is used. - out : ndarray, optional + 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. mode : {'raise', 'wrap', 'clip'}, optional @@ -99,7 +112,7 @@ def take(a, indices, axis=None, out=None, mode='raise'): Returns ------- - subarray : ndarray + out : ndarray (Ni..., Nj..., Nk...) The returned array has the same type as `a`. See Also @@ -107,6 +120,23 @@ def take(a, indices, axis=None, out=None, mode='raise'): compress : Take elements using a boolean mask ndarray.take : equivalent method + Notes + ----- + + By eliminating the inner loop in the description above, and using `s_` to + build simple slice objects, `take` can be expressed in terms of applying + fancy indexing to each 1-d slice:: + + Ni, Nk = a.shape[:axis], a.shape[axis+1:] + for ii in ndindex(Ni): + for kk in ndindex(Nj): + out[ii + s_[...,] + kk] = a[ii + s_[:,] + kk][indices] + + For this reason, it is equivalent to (but faster than) the following use + of `apply_along_axis`:: + + out = np.apply_along_axis(lambda a_1d: a_1d[indices], axis, a) + Examples -------- >>> a = [4, 3, 5, 7, 6, 8] -- cgit v1.2.1 From 0d749ad8dd9468a44ef1e6ed67f22eab03646d53 Mon Sep 17 00:00:00 2001 From: Vedant Misra Date: Fri, 1 Dec 2017 20:06:40 -0500 Subject: DOC: Fix minor typos in numpy/core/fromnumeric.py (#10072) --- 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 a335a9f4a..a5b16b88b 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -201,11 +201,11 @@ def reshape(a, newshape, order='C'): Notes ----- It is not always possible to change the shape of an array without - copying the data. If you want an error to be raise if the data is copied, + copying the data. If you want an error to be raised when the data is copied, you should assign the new shape to the shape attribute of the array:: >>> a = np.zeros((10, 2)) - # A transpose make the array non-contiguous + # 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. -- cgit v1.2.1 From e772a1a9bb9626490316e6c9ae8d57cd25cff33c Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 28 Dec 2017 07:40:57 +0000 Subject: ENH: Allow ptp to take an axis tuple and keepdims --- numpy/core/fromnumeric.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index a5b16b88b..8ba578c9f 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2178,7 +2178,7 @@ def cumproduct(a, axis=None, dtype=None, out=None): return _wrapfunc(a, 'cumprod', axis=axis, dtype=dtype, out=out) -def ptp(a, axis=None, out=None): +def ptp(a, axis=None, out=None, keepdims=np._NoValue): """ Range of values (maximum - minimum) along an axis. @@ -2188,14 +2188,31 @@ def ptp(a, axis=None, out=None): ---------- a : array_like Input values. - axis : int, optional + axis : None or int or tuple of ints, optional Axis along which to find the peaks. By default, flatten the - array. + array. `axis` may be negative, in + which case it counts from the last to the first axis. + + .. versionadded:: 1.15.0 + + If this is a tuple of ints, a reduction is performed on multiple + axes, instead of a single axis or all the axes as before. out : array_like Alternative output array in which to place the result. It must have the same shape and buffer length as the expected output, but the type of the output values will be cast if necessary. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `ptp` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-classes `sum` method does not implement `keepdims` any + exceptions will be raised. + Returns ------- ptp : ndarray @@ -2216,7 +2233,17 @@ def ptp(a, axis=None, out=None): array([1, 1]) """ - return _wrapfunc(a, 'ptp', axis=axis, out=out) + kwargs = {} + if keepdims is not np._NoValue: + kwargs['keepdims'] = keepdims + if type(a) is not mu.ndarray: + try: + ptp = a.ptp + except AttributeError: + pass + else: + return ptp(axis=axis, out=out, **kwargs) + return _methods._ptp(a, axis=axis, out=out, **kwargs) def amax(a, axis=None, out=None, keepdims=np._NoValue): -- cgit v1.2.1 From ce3d40e6e4b9de2f5e0179465b3cac779c3d3576 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 28 Dec 2017 07:56:00 +0000 Subject: DOC: Fix copy-paste mistakes in keepdims docstrings --- numpy/core/fromnumeric.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 8ba578c9f..61ab322df 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1812,7 +1812,7 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `sum` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -1966,7 +1966,7 @@ def any(a, axis=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `any` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -2051,7 +2051,7 @@ def all(a, axis=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `all` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -2210,7 +2210,7 @@ def ptp(a, axis=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `ptp` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -2275,7 +2275,7 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `amax` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -2376,7 +2376,7 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `amin` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -2518,7 +2518,7 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `prod` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -2917,7 +2917,7 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `mean` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -3024,7 +3024,7 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `std` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns @@ -3143,7 +3143,7 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): If the default value is passed, then `keepdims` will not be passed through to the `var` method of sub-classes of `ndarray`, however any non-default value will be. If the - sub-classes `sum` method does not implement `keepdims` any + sub-class' method does not implement `keepdims` any exceptions will be raised. Returns -- cgit v1.2.1 From 317ff845c7fc92bcab9e713e38f24cc898223f70 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 30 Dec 2017 07:48:21 +0000 Subject: DOC: Improve docs for searchsorted Also compare to the C++ functions with the same purpose. --- numpy/core/fromnumeric.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index a5b16b88b..558f2171a 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1076,6 +1076,15 @@ def searchsorted(a, v, side='left', sorter=None): corresponding elements in `v` were inserted before the indices, the order of `a` would be preserved. + Assuming that `a` is sorted: + + ====== ============================ + `side` returned index `i` satisfies + ====== ============================ + left ``a[i-1] < v <= a[i]`` + right ``a[i-1] <= v < a[i]`` + ====== ============================ + Parameters ---------- a : 1-D array_like @@ -1111,6 +1120,10 @@ 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` + (``side='left'``) and `bisect.bisect_right` (``side='right'``) functions, + which is also vectorized in the `v` argument. + Examples -------- >>> np.searchsorted([1,2,3,4,5], 3) -- cgit v1.2.1 From 858a6230f07ef7bf3a10becc36663976adeda8e8 Mon Sep 17 00:00:00 2001 From: Milo Date: Thu, 18 Jan 2018 00:40:20 +0100 Subject: DOC: Fix typo in docs for argpartition --- 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 8203684e9..43584349f 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -596,7 +596,7 @@ def partition(a, kth, axis=-1, kind='introselect', order=None): Element index to partition by. The k-th value of the element will be in its final sorted position and all smaller elements will be moved before it and all equal or greater elements behind - it. The order all elements in the partitions is undefined. If + it. The order of all elements in the partitions is undefined. If provided with a sequence of k-th it will partition all elements indexed by k-th of them into their sorted position at once. axis : int or None, optional -- cgit v1.2.1 From 1a0aef18318a07d46e9313e8a07dd4deacc0e2e8 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Fri, 23 Feb 2018 02:39:40 -0800 Subject: MAINT: Remove duplicate implementation for aliased functions. Fixes #10651 by replacing the behavior of `product` with that of `prod` --- numpy/core/fromnumeric.py | 192 ++++++++++++++++++---------------------------- 1 file changed, 75 insertions(+), 117 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 43584349f..7626b794d 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1895,54 +1895,6 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): out=out, **kwargs) -def product(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): - """ - Return the product of array elements over a given axis. - - See Also - -------- - prod : equivalent function; see for details. - - """ - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - return um.multiply.reduce(a, axis=axis, dtype=dtype, out=out, **kwargs) - - -def sometrue(a, axis=None, out=None, keepdims=np._NoValue): - """ - Check whether some values are true. - - Refer to `any` for full documentation. - - See Also - -------- - any : equivalent function - - """ - arr = asanyarray(a) - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - return arr.any(axis=axis, out=out, **kwargs) - - -def alltrue(a, axis=None, out=None, keepdims=np._NoValue): - """ - Check if all elements of input array are true. - - See Also - -------- - numpy.all : Equivalent function; see for details. - - """ - arr = asanyarray(a) - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - return arr.all(axis=axis, out=out, **kwargs) - def any(a, axis=None, out=None, keepdims=np._NoValue): """ @@ -2178,19 +2130,6 @@ def cumsum(a, axis=None, dtype=None, out=None): return _wrapfunc(a, 'cumsum', axis=axis, dtype=dtype, out=out) -def cumproduct(a, axis=None, dtype=None, out=None): - """ - Return the cumulative product over the given axis. - - - See Also - -------- - cumprod : equivalent function; see for details. - - """ - return _wrapfunc(a, 'cumprod', axis=axis, dtype=dtype, out=out) - - def ptp(a, axis=None, out=None, keepdims=np._NoValue): """ Range of values (maximum - minimum) along an axis. @@ -2706,62 +2645,6 @@ def ndim(a): return asarray(a).ndim -def rank(a): - """ - Return the number of dimensions of an array. - - If `a` is not already an array, a conversion is attempted. - Scalars are zero dimensional. - - .. note:: - This function is deprecated in NumPy 1.9 to avoid confusion with - `numpy.linalg.matrix_rank`. The ``ndim`` attribute or function - should be used instead. - - Parameters - ---------- - a : array_like - Array whose number of dimensions is desired. If `a` is not an array, - a conversion is attempted. - - Returns - ------- - number_of_dimensions : int - The number of dimensions in the array. - - See Also - -------- - ndim : equivalent function - ndarray.ndim : equivalent property - shape : dimensions of array - ndarray.shape : dimensions of array - - Notes - ----- - In the old Numeric package, `rank` was the term used for the number of - dimensions, but in NumPy `ndim` is used instead. - - Examples - -------- - >>> np.rank([1,2,3]) - 1 - >>> np.rank(np.array([[1,2,3],[4,5,6]])) - 2 - >>> np.rank(1) - 0 - - """ - # 2014-04-12, 1.9 - 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) - try: - return a.ndim - except AttributeError: - return asarray(a).ndim - - def size(a, axis=None): """ Return the number of elements along a given axis. @@ -3232,3 +3115,78 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): return _methods._var(a, axis=axis, dtype=dtype, out=out, ddof=ddof, **kwargs) + + +# Aliases of other functions. These have their own definitions only so that +# they can have unique docstrings. + +def product(*args, **kwargs): + """ + Return the product of array elements over a given axis. + + See Also + -------- + prod : equivalent function; see for details. + """ + return prod(*args, **kwargs) + + +def cumproduct(*args, **kwargs): + """ + Return the cumulative product over the given axis. + + See Also + -------- + cumprod : equivalent function; see for details. + """ + return cumprod(*args, **kwargs) + + +def sometrue(*args, **kwargs): + """ + Check whether some values are true. + + Refer to `any` for full documentation. + + See Also + -------- + any : equivalent function; see for details. + """ + return any(*args, **kwargs) + + +def alltrue(*args, **kwargs): + """ + Check if all elements of input array are true. + + See Also + -------- + numpy.all : Equivalent function; see for details. + """ + return all(*args, **kwargs) + + +def rank(a): + """ + Return the number of dimensions of an array. + + .. note:: + This function is deprecated in NumPy 1.9 to avoid confusion with + `numpy.linalg.matrix_rank`. The ``ndim`` attribute or function + should be used instead. + + See Also + -------- + ndim : equivalent non-deprecated function + + Notes + ----- + In the old Numeric package, `rank` was the term used for the number of + dimensions, but in NumPy `ndim` is used instead. + """ + # 2014-04-12, 1.9 + 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) + return ndim(a) -- cgit v1.2.1 From 1e45ea470eaae8d23c161f78931e946847e2b7e4 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 24 Feb 2018 23:32:29 -0800 Subject: BUG: Make np.partition and np.sort work on np.matrix when axis=None Both were making the normally valid assumption that flatten actually flattens, which turns out to be false for matrices. Old behavior: >>> a = np.matrix([[1, 2, 0]]) >>> np.partition(a, 1, axis=None) ValueError: kth(=1) out of bounds (1) >>> np.sort(a, axis=None) matrix([[1, 2, 0]]) --- numpy/core/fromnumeric.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 43584349f..4dfeb35ca 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -657,8 +657,9 @@ def partition(a, kth, axis=-1, kind='introselect', order=None): """ if axis is None: + # flatten returns (1, N) for np.matrix, so always use the last axis a = asanyarray(a).flatten() - axis = 0 + axis = -1 else: a = asanyarray(a).copy(order="K") a.partition(kth, axis=axis, kind=kind, order=order) @@ -840,8 +841,9 @@ def sort(a, axis=-1, kind='quicksort', order=None): """ if axis is None: + # flatten returns (1, N) for np.matrix, so always use the last axis a = asanyarray(a).flatten() - axis = 0 + axis = -1 else: a = asanyarray(a).copy(order="K") a.sort(axis=axis, kind=kind, order=order) -- cgit v1.2.1 From b344da928f06d867b0a4f41746c1bcb759a2fd8f Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Sun, 25 Feb 2018 11:25:21 +0100 Subject: MAINT: Unify reductions in fromnumeric.py --- numpy/core/fromnumeric.py | 95 +++++++++++++++-------------------------------- 1 file changed, 30 insertions(+), 65 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index de85c1143..10256c3c0 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -14,7 +14,6 @@ from . import numerictypes as nt from .numeric import asarray, array, asanyarray, concatenate from . import _methods - _dt_ = nt.sctype2char # functions that are methods @@ -26,7 +25,7 @@ __all__ = [ 'rank', 'ravel', 'repeat', 'reshape', 'resize', 'round_', 'searchsorted', 'shape', 'size', 'sometrue', 'sort', 'squeeze', 'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var', - ] +] _gentype = types.GeneratorType # save away Python sum @@ -62,6 +61,28 @@ def _wrapfunc(obj, method, *args, **kwds): return _wrapit(obj, method, *args, **kwds) +def _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs): + passkwargs = {} + for k, v in kwargs.items(): + if v is not np._NoValue: + passkwargs[k] = v + + if type(obj) is not mu.ndarray: + try: + reduction = getattr(obj, method) + except AttributeError: + pass + else: + # This branch is needed for reductions like any which don't + # support a dtype. + if dtype is not None: + return reduction(axis=axis, dtype=dtype, out=out, **passkwargs) + else: + return reduction(axis=axis, out=out, **passkwargs) + + return ufunc.reduce(obj, axis, dtype, out, **passkwargs) + + def take(a, indices, axis=None, out=None, mode='raise'): """ Take elements from an array along an axis. @@ -1195,7 +1216,7 @@ def resize(a, new_shape): n_copies = n_copies + 1 extra = Na - extra - a = concatenate((a,)*n_copies) + a = concatenate((a,) * n_copies) if extra > 0: a = a[:-extra] @@ -1877,25 +1898,14 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): -128 """ - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims if isinstance(a, _gentype): res = _sum_(a) if out is not None: out[...] = res return out return res - if type(a) is not mu.ndarray: - try: - sum = a.sum - except AttributeError: - pass - else: - return sum(axis=axis, dtype=dtype, out=out, **kwargs) - return _methods._sum(a, axis=axis, dtype=dtype, - out=out, **kwargs) + return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims) def any(a, axis=None, out=None, keepdims=np._NoValue): @@ -1978,11 +1988,7 @@ def any(a, axis=None, out=None, keepdims=np._NoValue): (191614240, 191614240) """ - arr = asanyarray(a) - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - return arr.any(axis=axis, out=out, **kwargs) + return _wrapreduction(a, np.logical_or, 'any', axis, None, out, keepdims=keepdims) def all(a, axis=None, out=None, keepdims=np._NoValue): @@ -2058,11 +2064,7 @@ def all(a, axis=None, out=None, keepdims=np._NoValue): (28293632, 28293632, array([ True])) """ - arr = asanyarray(a) - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - return arr.all(axis=axis, out=out, **kwargs) + return _wrapreduction(a, np.logical_and, 'all', axis, None, out, keepdims=keepdims) def cumsum(a, axis=None, dtype=None, out=None): @@ -2285,20 +2287,7 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue): 4.0 """ - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - - if type(a) is not mu.ndarray: - try: - amax = a.max - except AttributeError: - pass - else: - return amax(axis=axis, out=out, **kwargs) - - return _methods._amax(a, axis=axis, - out=out, **kwargs) + return _wrapreduction(a, np.maximum, 'max', axis, None, out, keepdims=keepdims) def amin(a, axis=None, out=None, keepdims=np._NoValue): @@ -2386,19 +2375,7 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue): 0.0 """ - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - if type(a) is not mu.ndarray: - try: - amin = a.min - except AttributeError: - pass - else: - return amin(axis=axis, out=out, **kwargs) - - return _methods._amin(a, axis=axis, - out=out, **kwargs) + return _wrapreduction(a, np.minimum, 'min', axis, None, out, keepdims=keepdims) def alen(a): @@ -2532,19 +2509,7 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): True """ - kwargs = {} - if keepdims is not np._NoValue: - kwargs['keepdims'] = keepdims - if type(a) is not mu.ndarray: - try: - prod = a.prod - except AttributeError: - pass - else: - return prod(axis=axis, dtype=dtype, out=out, **kwargs) - - return _methods._prod(a, axis=axis, dtype=dtype, - out=out, **kwargs) + return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out, keepdims=keepdims) def cumprod(a, axis=None, dtype=None, out=None): -- cgit v1.2.1 From 6d950b383bff4ac2448b3f6a1e7573e7ea176051 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 26 Feb 2018 21:31:14 -0800 Subject: DEP: Deprecate np.sum(generator) Fixes #10652 Introduced in a13aad3ac33b629f3e696b4d4d5dbf4b5605d567 --- numpy/core/fromnumeric.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index de85c1143..6c7ef4c1f 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1881,6 +1881,12 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): if keepdims is not np._NoValue: kwargs['keepdims'] = keepdims if isinstance(a, _gentype): + # 2018-02-25, 1.15.0 + warnings.warn( + "Calling np.sum(generator) is deprecated, and in the future will give a different result. " + "Use np.sum(np.from_iter(generator)) or the python sum builtin instead.", + DeprecationWarning, stacklevel=2) + res = _sum_(a) if out is not None: out[...] = res -- cgit v1.2.1 From 864a431fd6047b1c26a7001bd2e3d989a5320e0f Mon Sep 17 00:00:00 2001 From: Lakshay Garg Date: Fri, 23 Mar 2018 00:09:58 +0530 Subject: add stablesort in np.sort and point to mergesort Closes #10784 --- numpy/core/fromnumeric.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 10256c3c0..ddf3314cf 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -764,7 +764,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'}, optional + kind : {'quicksort', 'mergesort', 'heapsort', '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 @@ -797,9 +797,10 @@ def sort(a, axis=-1, kind='quicksort', order=None): =========== ======= ============= ============ ======= 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 + 'quicksort' 1 O(n^2) 0 no + 'mergesort' 2 O(n*log(n)) ~n/2 yes + 'stable' 2 O(n*log(n)) ~n/2 yes + 'heapsort' 3 O(n*log(n)) 0 no =========== ======= ============= ============ ======= All the sort algorithms make temporary copies of the data when @@ -886,7 +887,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'}, optional + kind : {'quicksort', 'mergesort', 'heapsort', '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 4a2891748ab9ac8cafd7aaef10222c761e96f892 Mon Sep 17 00:00:00 2001 From: Lakshay Garg Date: Thu, 29 Mar 2018 12:39:30 +0530 Subject: Remove NPY_STABLESORT enum --- numpy/core/fromnumeric.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index ddf3314cf..63279ffb3 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -794,14 +794,13 @@ def sort(a, axis=-1, kind='quicksort', order=None): order. The three available algorithms 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 - 'stable' 2 O(n*log(n)) ~n/2 yes - 'heapsort' 3 O(n*log(n)) 0 no - =========== ======= ============= ============ ======= + =========== ======= ============= ============ ======== + 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 + =========== ======= ============= ============ ======== All the sort algorithms make temporary copies of the data when sorting along any but the last axis. Consequently, sorting along @@ -830,6 +829,10 @@ def sort(a, axis=-1, kind='quicksort', order=None): heapsort when it does not make enough progress. This makes its 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. + Examples -------- >>> a = np.array([[1,4],[3,1]]) -- cgit v1.2.1 From 2ee7c72e56b5ef16f3838f86de8ad0d435b9b4e0 Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Fri, 30 Mar 2018 08:32:27 -0600 Subject: BUG: np.squeeze() now respects older API axis expectation * Fixes Issue #10779 by removing the interception of an otherwise normal Exception when an object implemented with the expectation that squeeze() does not accept an axis argument receives an axis argument * Added unit tests that enforce respect for the old API expectation in objects, and ensure that silent success (or forced usage of the new API on objects) is no longer the case * Updated compatibility notes to explain this change --- numpy/core/fromnumeric.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 10256c3c0..e81a4a039 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1276,13 +1276,10 @@ def squeeze(a, axis=None): squeeze = a.squeeze except AttributeError: return _wrapit(a, 'squeeze') - try: - # First try to use the new axis= parameter - return squeeze(axis=axis) - except TypeError: - # For backwards compatibility + if axis is None: return squeeze() - + else: + return squeeze(axis=axis) def diagonal(a, offset=0, axis1=0, axis2=1): """ -- cgit v1.2.1 From 6b728d19150f013ba885451f79990c30e872fe8f Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Tue, 24 Apr 2018 15:44:17 +0200 Subject: ENH: Implement initial kwarg for ufunc.add.reduce --- numpy/core/fromnumeric.py | 76 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 8 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 948c2139d..75bcedd81 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1812,7 +1812,7 @@ def clip(a, a_min, a_max, out=None): return _wrapfunc(a, 'clip', a_min, a_max, out=out) -def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): +def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Sum of array elements over a given axis. @@ -1851,6 +1851,10 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): `ndarray`, however any non-default value will be. If the sub-class' method does not implement `keepdims` any exceptions will be raised. + initial : scalar, optional + Starting value for the sum. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 Returns ------- @@ -1898,6 +1902,10 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): >>> np.ones(128, dtype=np.int8).sum(dtype=np.int8) -128 + You can also start the sum with a value other than zero: + + >>> np.sum([10], initial=5) + 15 """ if isinstance(a, _gentype): # 2018-02-25, 1.15.0 @@ -1912,7 +1920,8 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): return out return res - return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims) + return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims, + initial=initial) def any(a, axis=None, out=None, keepdims=np._NoValue): @@ -2209,7 +2218,7 @@ def ptp(a, axis=None, out=None, keepdims=np._NoValue): return _methods._ptp(a, axis=axis, out=out, **kwargs) -def amax(a, axis=None, out=None, keepdims=np._NoValue): +def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Return the maximum of an array or maximum along an axis. @@ -2241,6 +2250,13 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue): sub-class' method does not implement `keepdims` any exceptions will be raised. + initial : scalar, optional + The minimum value of an output element. Must be present to allow + computation on empty slice. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 + + Returns ------- amax : ndarray or scalar @@ -2293,11 +2309,26 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue): >>> np.nanmax(b) 4.0 + You can use an initial value to compute the maximum of an empty slice, or + to initialize it to a different value: + + >>> np.max([[-50], [10]], axis=-1, initial=0) + array([ 0, 10]) + + Notice that the initial value is used as one of the elements for which the + maximum is determined, unlike for the default argument Python's max + function, which is only used for empty iterables. + + >>> np.max([5], initial=6) + 6 + >>> max([5], default=6) + 5 """ - return _wrapreduction(a, np.maximum, 'max', axis, None, out, keepdims=keepdims) + return _wrapreduction(a, np.maximum, 'max', axis, None, out, keepdims=keepdims, + initial=initial) -def amin(a, axis=None, out=None, keepdims=np._NoValue): +def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Return the minimum of an array or minimum along an axis. @@ -2329,6 +2360,12 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue): sub-class' method does not implement `keepdims` any exceptions will be raised. + initial : scalar, optional + The maximum value of an output element. Must be present to allow + computation on empty slice. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 + Returns ------- amin : ndarray or scalar @@ -2381,8 +2418,22 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue): >>> np.nanmin(b) 0.0 + >>> np.min([[-50], [10]], axis=-1, initial=0) + array([-50, 0]) + + Notice that the initial value is used as one of the elements for which the + minimum is determined, unlike for the default argument Python's max + function, which is only used for empty iterables. + + Notice that this isn't the same as Python's ``default`` argument. + + >>> np.min([6], initial=5) + 5 + >>> min([6], default=5) + 6 """ - return _wrapreduction(a, np.minimum, 'min', axis, None, out, keepdims=keepdims) + return _wrapreduction(a, np.minimum, 'min', axis, None, out, keepdims=keepdims, + initial=initial) def alen(a): @@ -2418,7 +2469,7 @@ def alen(a): return len(array(a, ndmin=1)) -def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): +def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Return the product of array elements over a given axis. @@ -2458,6 +2509,10 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): `ndarray`, however any non-default value will be. If the sub-class' method does not implement `keepdims` any exceptions will be raised. + initial : scalar, optional + The starting value for this product. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 Returns ------- @@ -2515,8 +2570,13 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): >>> np.prod(x).dtype == int True + You can also start the product with a value other than one: + + >>> np.prod([1, 2], initial=5) + 10 """ - return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out, keepdims=keepdims) + return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out, keepdims=keepdims, + initial=initial) def cumprod(a, axis=None, dtype=None, out=None): -- cgit v1.2.1 From d7e0c7e34b293ab32a46960c65d063446115d4e8 Mon Sep 17 00:00:00 2001 From: Marten van Kerkwijk Date: Sun, 29 Apr 2018 15:24:01 -0400 Subject: MAINT: move matrix tests in core, polynomial to matrixlib. --- numpy/core/fromnumeric.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 75bcedd81..58903d411 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1336,10 +1336,10 @@ def diagonal(a, offset=0, axis1=0, axis2=1): Returns ------- array_of_diagonals : ndarray - If `a` is 2-D and not a `matrix`, a 1-D array of the same type as `a` - containing the diagonal is returned. If `a` is a `matrix`, a 1-D + If `a` is 2-D, a 1-D array of the same type as `a` containing the + diagonal is returned (except if `a` is a `matrix`, in which case a 1-D array containing the diagonal is returned in order to maintain - backward compatibility. + 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. @@ -1496,10 +1496,9 @@ def ravel(a, order='C'): Returns ------- y : array_like - If `a` is a matrix, y is a 1-D ndarray, otherwise y is an array of - the same subtype as `a`. The shape of the returned array is - ``(a.size,)``. Matrices are special cased for backward - compatibility. + y is an array of the same subtype as `a`, with shape ``(a.size,)`` + (Note: matrices are special-cases for backward compatibility: if `a` + is a matrix, y is a 1-D ndarray.) See Also -------- -- cgit v1.2.1 From 8e74c991d1336bd51e71dc492544223055c130f4 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Mon, 14 May 2018 15:12:33 -0600 Subject: DOC: Revise some of the docstrings. [ci skip] --- numpy/core/fromnumeric.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 58903d411..0db5663f9 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1336,10 +1336,11 @@ def diagonal(a, offset=0, axis1=0, axis2=1): Returns ------- array_of_diagonals : ndarray - If `a` is 2-D, a 1-D array of the same type as `a` containing the - diagonal is returned (except if `a` is a `matrix`, in which case a 1-D - array containing the diagonal is returned in order to maintain - backward compatibility). + If `a` is 2-D, then a 1-D array containing the diagonal and of the + 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. @@ -1496,9 +1497,9 @@ def ravel(a, order='C'): Returns ------- y : array_like - y is an array of the same subtype as `a`, with shape ``(a.size,)`` - (Note: matrices are special-cases for backward compatibility: if `a` - is a matrix, y is a 1-D ndarray.) + y is an array of the same subtype as `a`, with shape ``(a.size,)``. + Note that matrices are special cased for backward compatibility, if `a` + is a matrix, then y is a 1-D ndarray. See Also -------- -- cgit v1.2.1 From 905e906d55fdcb8cc215de8aa287ea9654d1c95c Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 28 Feb 2017 14:03:27 +0000 Subject: ENH: Add (put|take)_along_axis as described in #8708 This is the reduced version that does not allow any insertion of extra dimensions --- numpy/core/fromnumeric.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 0db5663f9..d1aae0aa0 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -140,6 +140,7 @@ def take(a, indices, axis=None, out=None, mode='raise'): -------- compress : Take elements using a boolean mask ndarray.take : equivalent method + take_along_axis : Take elements by matching the array and the index arrays Notes ----- @@ -478,6 +479,7 @@ def put(a, ind, v, mode='raise'): See Also -------- putmask, place + put_along_axis : Put elements by matching the array and the index arrays Examples -------- @@ -723,7 +725,9 @@ def argpartition(a, kth, axis=-1, kind='introselect', order=None): ------- index_array : ndarray, int Array of indices that partition `a` along the specified axis. - In other words, ``a[index_array]`` yields a partitioned `a`. + If `a` is one-dimensional, ``a[index_array]`` yields a partitioned `a`. + More generally, ``np.take_along_axis(a, index_array, axis=a)`` always + yields the partitioned `a`, irrespective of dimensionality. See Also -------- @@ -904,6 +908,8 @@ def argsort(a, axis=-1, kind='quicksort', order=None): index_array : ndarray, int 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. See Also -------- -- cgit v1.2.1 From 83828f52b287fefb3d8753a21bd3441997a4d687 Mon Sep 17 00:00:00 2001 From: Mike Toews Date: Sat, 16 Jun 2018 18:18:19 +1200 Subject: HTTP -> HTTPS, and other linkrot fixes --- 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 d1aae0aa0..5b67a0dc5 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2777,11 +2777,11 @@ def around(a, decimals=0, out=None): References ---------- - .. [1] "Lecture Notes on the Status of IEEE 754", William Kahan, - http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF + .. [1] "Lecture Notes on the Status of IEEE 754", William Kahan, + https://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF .. [2] "How Futile are Mindless Assessments of Roundoff in Floating-Point Computation?", William Kahan, - http://www.cs.berkeley.edu/~wkahan/Mindless.pdf + https://people.eecs.berkeley.edu/~wkahan/Mindless.pdf Examples -------- -- cgit v1.2.1 From 917b0794e8e68a443f94299a80c51491cdc1c6cb Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 25 Jun 2018 23:56:16 -0700 Subject: DOC: Clear up confusion between np.where(cond) and np.where(cond, x, y) Eliminates all mentions of `np.where(cond)`, instead pointing the reader to np.nonzero. Also changes some example numbers to avoid collisions, making them easier to follow. Some minor doc improvements for np.ma.where too. --- numpy/core/fromnumeric.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 5b67a0dc5..373e0fde8 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1615,16 +1615,16 @@ def nonzero(a): Examples -------- - >>> x = np.array([[1,0,0], [0,2,0], [1,1,0]]) + >>> x = np.array([[3, 0, 0], [0, 4, 0], [5, 6, 0]]) >>> x - array([[1, 0, 0], - [0, 2, 0], - [1, 1, 0]]) + array([[3, 0, 0], + [0, 4, 0], + [5, 6, 0]]) >>> np.nonzero(x) (array([0, 1, 2, 2]), array([0, 1, 0, 1])) >>> x[np.nonzero(x)] - array([1, 2, 1, 1]) + array([3, 4, 5, 6]) >>> np.transpose(np.nonzero(x)) array([[0, 0], [1, 1], @@ -1636,7 +1636,7 @@ def nonzero(a): boolean array and since False is interpreted as 0, np.nonzero(a > 3) yields the indices of the `a` where the condition is true. - >>> a = np.array([[1,2,3],[4,5,6],[7,8,9]]) + >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> a > 3 array([[False, False, False], [ True, True, True], @@ -1644,7 +1644,14 @@ def nonzero(a): >>> np.nonzero(a > 3) (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) - The ``nonzero`` method of the boolean array can also be called. + Using this result to index `a` is equivalent to using the mask directly: + + >>> a[np.nonzero(a > 3)] + array([4, 5, 6, 7, 8, 9]) + >>> a[a > 3] # prefer this spelling + array([4, 5, 6, 7, 8, 9]) + + ``nonzero`` can also be called as a method of the array. >>> (a > 3).nonzero() (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) -- cgit v1.2.1 From 000e7d4edae1fa2257f72e889e22f0f2942f8f33 Mon Sep 17 00:00:00 2001 From: Anner Date: Tue, 3 Jul 2018 10:33:15 +0900 Subject: include warning in np.resize() docs I find it counterintuitive that resizing a numpy array does NOT consider dimensions independent, but simply takes the first N elements of the input array that fit into the output array. I was expecting something more like `cv2.resize()` where axes are treated separately, and some form of interpolation is applied to each dimension. numpy resizes an old 5x5x2 array into a new array with new = np.resize(old, (4, 4, 2)) by simply copying the first 4 * 4 * 2 entries from old into new. (e.g. old[0, 4, :] becomes new[1, 0, :]) This is a problem if we would like simple interpolation, or if different axes represent different entities. (If the above example is an image, the top right most pixel would get warped all the way to the left, which is most likely not the intention) In response to my issue #11478: 'resize() is unintuitive by not treating axes separately?' A warning in the docs might prevent some confusion. For a discussion on the issue and a possible solution, see --- numpy/core/fromnumeric.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 373e0fde8..a87437a47 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1197,7 +1197,17 @@ def resize(a, new_shape): See Also -------- ndarray.resize : resize an array in-place. - + + Notes + ----- + Warning: This functionality does **not** consider axes separately, + i.e. it does not apply interpolation/extrapolation of some sort. + It simply takes the first `np.prod(new_shape)` elements of `a`, + disregarding axes, and fills the returned array with these elements. + (This is in case the new shape is smaller. For larger, see above.) + This functionality is therefor not suitable to resize images, + or data where each axis represents a separate and distinct entity. + Examples -------- >>> a=np.array([[0,1],[2,3]]) -- cgit v1.2.1 From a6694870220b8b4ab18796b6c19e1dc45d0805cc Mon Sep 17 00:00:00 2001 From: Anner Date: Thu, 5 Jul 2018 10:48:22 +0900 Subject: Update resize notes according to mattip's comments removed 'simple' altered sentence describing which items are taken from `old` into `new` therefor -> therefore --- 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 a87437a47..57410d194 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1201,11 +1201,11 @@ def resize(a, new_shape): Notes ----- Warning: This functionality does **not** consider axes separately, - i.e. it does not apply interpolation/extrapolation of some sort. - It simply takes the first `np.prod(new_shape)` elements of `a`, - disregarding axes, and fills the returned array with these elements. + i.e. it does not apply interpolation/extrapolation. + It fills the return array with the required number of elements, + taken from `a` as they are laid out in memory, disregarding strides and axes. (This is in case the new shape is smaller. For larger, see above.) - This functionality is therefor not suitable to resize images, + This functionality is therefore not suitable to resize images, or data where each axis represents a separate and distinct entity. Examples -- cgit v1.2.1 From d67ace6f9753ca7ed0084ffc1ea5806bc5182602 Mon Sep 17 00:00:00 2001 From: Anner Date: Fri, 6 Jul 2018 11:40:09 +0900 Subject: removed spaces. improved right side outlining --- 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 57410d194..b9cc98cae 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1197,17 +1197,17 @@ def resize(a, new_shape): See Also -------- ndarray.resize : resize an array in-place. - + Notes ----- Warning: This functionality does **not** consider axes separately, i.e. it does not apply interpolation/extrapolation. - It fills the return array with the required number of elements, - taken from `a` as they are laid out in memory, disregarding strides and axes. + It fills the return array with the required number of elements, taken + from `a` as they are laid out in memory, disregarding strides and axes. (This is in case the new shape is smaller. For larger, see above.) This functionality is therefore not suitable to resize images, or data where each axis represents a separate and distinct entity. - + Examples -------- >>> a=np.array([[0,1],[2,3]]) -- cgit v1.2.1 From 607842ab59b0479c485eb6fa30778f47dccc224a Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Sat, 6 Oct 2018 22:53:53 +0200 Subject: ENH: __array_function__ support for most of numpy.core With the notable exceptions of np.einsum and np.block. xref GH12028 --- numpy/core/fromnumeric.py | 232 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 220 insertions(+), 12 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index b9cc98cae..81a1a66b7 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -12,6 +12,7 @@ from . import multiarray as mu from . import umath as um from . import numerictypes as nt from .numeric import asarray, array, asanyarray, concatenate +from .overrides import array_function_dispatch from . import _methods _dt_ = nt.sctype2char @@ -83,6 +84,11 @@ def _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs): return ufunc.reduce(obj, axis, dtype, out, **passkwargs) +def _take_dispatcher(a, indices, axis=None, out=None, mode=None): + return (a, out) + + +@array_function_dispatch(_take_dispatcher) def take(a, indices, axis=None, out=None, mode='raise'): """ Take elements from an array along an axis. @@ -181,7 +187,12 @@ def take(a, indices, axis=None, out=None, mode='raise'): return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode) +def _reshape_dispatcher(a, newshape, order=None): + return (a,) + + # not deprecated --- copy if necessary, view otherwise +@array_function_dispatch(_reshape_dispatcher) def reshape(a, newshape, order='C'): """ Gives a new shape to an array without changing its data. @@ -279,6 +290,14 @@ def reshape(a, newshape, order='C'): return _wrapfunc(a, 'reshape', newshape, order=order) +def _choose_dispatcher(a, choices, out=None, mode=None): + yield a + for c in choices: + yield c + yield out + + +@array_function_dispatch(_choose_dispatcher) def choose(a, choices, out=None, mode='raise'): """ Construct an array from an index array and a set of arrays to choose from. @@ -401,6 +420,11 @@ def choose(a, choices, out=None, mode='raise'): return _wrapfunc(a, 'choose', choices, out=out, mode=mode) +def _repeat_dispatcher(a, repeats, axis=None): + return (a,) + + +@array_function_dispatch(_repeat_dispatcher) def repeat(a, repeats, axis=None): """ Repeat elements of an array. @@ -445,6 +469,11 @@ def repeat(a, repeats, axis=None): return _wrapfunc(a, 'repeat', repeats, axis=axis) +def _put_dispatcher(a, ind, v, mode=None): + return (a, ind, v) + + +@array_function_dispatch(_put_dispatcher) def put(a, ind, v, mode='raise'): """ Replaces specified elements of an array with given values. @@ -503,6 +532,11 @@ def put(a, ind, v, mode='raise'): return put(ind, v, mode=mode) +def _swapaxes_dispatcher(a, axis1, axis2): + return (a,) + + +@array_function_dispatch(_swapaxes_dispatcher) def swapaxes(a, axis1, axis2): """ Interchange two axes of an array. @@ -549,6 +583,11 @@ def swapaxes(a, axis1, axis2): return _wrapfunc(a, 'swapaxes', axis1, axis2) +def _transpose_dispatcher(a, axes=None): + return (a,) + + +@array_function_dispatch(_transpose_dispatcher) def transpose(a, axes=None): """ Permute the dimensions of an array. @@ -598,6 +637,11 @@ def transpose(a, axes=None): return _wrapfunc(a, 'transpose', axes) +def _partition_dispatcher(a, kth, axis=None, kind=None, order=None): + return (a,) + + +@array_function_dispatch(_partition_dispatcher) def partition(a, kth, axis=-1, kind='introselect', order=None): """ Return a partitioned copy of an array. @@ -689,6 +733,11 @@ def partition(a, kth, axis=-1, kind='introselect', order=None): return a +def _argpartition_dispatcher(a, kth, axis=None, kind=None, order=None): + return (a,) + + +@array_function_dispatch(_argpartition_dispatcher) def argpartition(a, kth, axis=-1, kind='introselect', order=None): """ Perform an indirect partition along the given axis using the @@ -757,6 +806,11 @@ def argpartition(a, kth, axis=-1, kind='introselect', order=None): return _wrapfunc(a, 'argpartition', kth, axis=axis, kind=kind, order=order) +def _sort_dispatcher(a, axis=None, kind=None, order=None): + return (a,) + + +@array_function_dispatch(_sort_dispatcher) def sort(a, axis=-1, kind='quicksort', order=None): """ Return a sorted copy of an array. @@ -879,6 +933,11 @@ def sort(a, axis=-1, kind='quicksort', order=None): return a +def _argsort_dispatcher(a, axis=None, kind=None, order=None): + return (a,) + + +@array_function_dispatch(_argsort_dispatcher) def argsort(a, axis=-1, kind='quicksort', order=None): """ Returns the indices that would sort an array. @@ -973,6 +1032,11 @@ def argsort(a, axis=-1, kind='quicksort', order=None): return _wrapfunc(a, 'argsort', axis=axis, kind=kind, order=order) +def _argmax_dispatcher(a, axis=None, out=None): + return (a, out) + + +@array_function_dispatch(_argmax_dispatcher) def argmax(a, axis=None, out=None): """ Returns the indices of the maximum values along an axis. @@ -1037,6 +1101,11 @@ def argmax(a, axis=None, out=None): return _wrapfunc(a, 'argmax', axis=axis, out=out) +def _argmin_dispatcher(a, axis=None, out=None): + return (a, out) + + +@array_function_dispatch(_argmin_dispatcher) def argmin(a, axis=None, out=None): """ Returns the indices of the minimum values along an axis. @@ -1101,6 +1170,11 @@ def argmin(a, axis=None, out=None): return _wrapfunc(a, 'argmin', axis=axis, out=out) +def _searchsorted_dispatcher(a, v, side=None, sorter=None): + return (a, v, sorter) + + +@array_function_dispatch(_searchsorted_dispatcher) def searchsorted(a, v, side='left', sorter=None): """ Find indices where elements should be inserted to maintain order. @@ -1170,6 +1244,11 @@ def searchsorted(a, v, side='left', sorter=None): return _wrapfunc(a, 'searchsorted', v, side=side, sorter=sorter) +def _resize_dispatcher(a, new_shape): + return (a,) + + +@array_function_dispatch(_resize_dispatcher) def resize(a, new_shape): """ Return a new array with the specified shape. @@ -1243,6 +1322,11 @@ def resize(a, new_shape): return reshape(a, new_shape) +def _squeeze_dispatcher(a, axis=None): + return (a,) + + +@array_function_dispatch(_squeeze_dispatcher) def squeeze(a, axis=None): """ Remove single-dimensional entries from the shape of an array. @@ -1301,6 +1385,12 @@ def squeeze(a, axis=None): else: return squeeze(axis=axis) + +def _diagonal_dispatcher(a, offset=None, axis1=None, axis2=None): + return (a,) + + +@array_function_dispatch(_diagonal_dispatcher) def diagonal(a, offset=0, axis1=0, axis2=1): """ Return specified diagonals. @@ -1415,6 +1505,12 @@ def diagonal(a, offset=0, axis1=0, axis2=1): return asanyarray(a).diagonal(offset=offset, axis1=axis1, axis2=axis2) +def _trace_dispatcher( + a, offset=None, axis1=None, axis2=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_trace_dispatcher) def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None): """ Return the sum along diagonals of the array. @@ -1478,6 +1574,11 @@ def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None): return asanyarray(a).trace(offset=offset, axis1=axis1, axis2=axis2, dtype=dtype, out=out) +def _ravel_dispatcher(a, order=None): + return (a,) + + +@array_function_dispatch(_ravel_dispatcher) def ravel(a, order='C'): """Return a contiguous flattened array. @@ -1584,6 +1685,11 @@ def ravel(a, order='C'): return asanyarray(a).ravel(order=order) +def _nonzero_dispatcher(a): + return (a,) + + +@array_function_dispatch(_nonzero_dispatcher) def nonzero(a): """ Return the indices of the elements that are non-zero. @@ -1670,6 +1776,11 @@ def nonzero(a): return _wrapfunc(a, 'nonzero') +def _shape_dispatcher(a): + return (a,) + + +@array_function_dispatch(_shape_dispatcher) def shape(a): """ Return the shape of an array. @@ -1715,6 +1826,11 @@ def shape(a): return result +def _compress_dispatcher(condition, a, axis=None, out=None): + return (condition, a, out) + + +@array_function_dispatch(_compress_dispatcher) def compress(condition, a, axis=None, out=None): """ Return selected slices of an array along given axis. @@ -1778,6 +1894,11 @@ 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): + return (a, a_min, a_max) + + +@array_function_dispatch(_clip_dispatcher) def clip(a, a_min, a_max, out=None): """ Clip (limit) the values in an array. @@ -1835,6 +1956,12 @@ def clip(a, a_min, a_max, out=None): return _wrapfunc(a, 'clip', a_min, a_max, out=out) +def _sum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, + initial=None): + return (a, out) + + +@array_function_dispatch(_sum_dispatcher) def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Sum of array elements over a given axis. @@ -1947,6 +2074,11 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._No initial=initial) +def _any_dispatcher(a, axis=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_any_dispatcher) def any(a, axis=None, out=None, keepdims=np._NoValue): """ Test whether any array element along a given axis evaluates to True. @@ -2030,6 +2162,11 @@ def any(a, axis=None, out=None, keepdims=np._NoValue): return _wrapreduction(a, np.logical_or, 'any', axis, None, out, keepdims=keepdims) +def _all_dispatcher(a, axis=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_all_dispatcher) def all(a, axis=None, out=None, keepdims=np._NoValue): """ Test whether all array elements along a given axis evaluate to True. @@ -2106,6 +2243,11 @@ def all(a, axis=None, out=None, keepdims=np._NoValue): return _wrapreduction(a, np.logical_and, 'all', axis, None, out, keepdims=keepdims) +def _cumsum_dispatcher(a, axis=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_cumsum_dispatcher) def cumsum(a, axis=None, dtype=None, out=None): """ Return the cumulative sum of the elements along a given axis. @@ -2173,6 +2315,11 @@ def cumsum(a, axis=None, dtype=None, out=None): return _wrapfunc(a, 'cumsum', axis=axis, dtype=dtype, out=out) +def _ptp_dispatcher(a, axis=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_ptp_dispatcher) def ptp(a, axis=None, out=None, keepdims=np._NoValue): """ Range of values (maximum - minimum) along an axis. @@ -2241,6 +2388,11 @@ 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): + return (a, out) + + +@array_function_dispatch(_amax_dispatcher) def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Return the maximum of an array or maximum along an axis. @@ -2351,6 +2503,11 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): initial=initial) +def _amin_dispatcher(a, axis=None, out=None, keepdims=None, initial=None): + return (a, out) + + +@array_function_dispatch(_amin_dispatcher) def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Return the minimum of an array or minimum along an axis. @@ -2459,6 +2616,11 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue): initial=initial) +def _alen_dispathcer(a): + return (a,) + + +@array_function_dispatch(_alen_dispathcer) def alen(a): """ Return the length of the first dimension of the input array. @@ -2492,6 +2654,12 @@ def alen(a): return len(array(a, ndmin=1)) +def _prod_dispatcher( + a, axis=None, dtype=None, out=None, keepdims=None, initial=None): + return (a, out) + + +@array_function_dispatch(_prod_dispatcher) def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue): """ Return the product of array elements over a given axis. @@ -2602,6 +2770,11 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._N initial=initial) +def _cumprod_dispatcher(a, axis=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_cumprod_dispatcher) def cumprod(a, axis=None, dtype=None, out=None): """ Return the cumulative product of elements along a given axis. @@ -2665,6 +2838,11 @@ def cumprod(a, axis=None, dtype=None, out=None): return _wrapfunc(a, 'cumprod', axis=axis, dtype=dtype, out=out) +def _ndim_dispatcher(a): + return (a,) + + +@array_function_dispatch(_ndim_dispatcher) def ndim(a): """ Return the number of dimensions of an array. @@ -2702,6 +2880,11 @@ def ndim(a): return asarray(a).ndim +def _size_dispatcher(a, axis=None): + return (a,) + + +@array_function_dispatch(_size_dispatcher) def size(a, axis=None): """ Return the number of elements along a given axis. @@ -2748,6 +2931,11 @@ def size(a, axis=None): return asarray(a).shape[axis] +def _around_dispatcher(a, decimals=None, out=None): + return (a, out) + + +@array_function_dispatch(_around_dispatcher) def around(a, decimals=0, out=None): """ Evenly round to the given number of decimals. @@ -2817,20 +3005,11 @@ def around(a, decimals=0, out=None): return _wrapfunc(a, 'round', decimals=decimals, out=out) -def round_(a, decimals=0, out=None): - """ - Round an array to the given number of decimals. - - Refer to `around` for full documentation. - - See Also - -------- - around : equivalent function - - """ - return around(a, decimals=decimals, out=out) +def _mean_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None): + return (a, out) +@array_function_dispatch(_mean_dispatcher) def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): """ Compute the arithmetic mean along the specified axis. @@ -2937,6 +3116,12 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): out=out, **kwargs) +def _std_dispatcher( + a, axis=None, dtype=None, out=None, ddof=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_std_dispatcher) def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): """ Compute the standard deviation along the specified axis. @@ -3055,6 +3240,12 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): **kwargs) +def _var_dispatcher( + a, axis=None, dtype=None, out=None, ddof=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_var_dispatcher) def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): """ Compute the variance along the specified axis. @@ -3177,6 +3368,19 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): # Aliases of other functions. These have their own definitions only so that # they can have unique docstrings. +@array_function_dispatch(_around_dispatcher) +def round_(a, decimals=0, out=None): + """ + Round an array to the given number of decimals. + + See Also + -------- + around : equivalent function; see for details. + """ + return around(a, decimals=decimals, out=out) + + +@array_function_dispatch(_prod_dispatcher, verify=False) def product(*args, **kwargs): """ Return the product of array elements over a given axis. @@ -3188,6 +3392,7 @@ def product(*args, **kwargs): return prod(*args, **kwargs) +@array_function_dispatch(_cumprod_dispatcher, verify=False) def cumproduct(*args, **kwargs): """ Return the cumulative product over the given axis. @@ -3199,6 +3404,7 @@ def cumproduct(*args, **kwargs): return cumprod(*args, **kwargs) +@array_function_dispatch(_any_dispatcher, verify=False) def sometrue(*args, **kwargs): """ Check whether some values are true. @@ -3212,6 +3418,7 @@ def sometrue(*args, **kwargs): return any(*args, **kwargs) +@array_function_dispatch(_all_dispatcher, verify=False) def alltrue(*args, **kwargs): """ Check if all elements of input array are true. @@ -3223,6 +3430,7 @@ def alltrue(*args, **kwargs): return all(*args, **kwargs) +@array_function_dispatch(_ndim_dispatcher) def rank(a): """ Return the number of dimensions of an array. -- cgit v1.2.1 From 2eb4d5f137d45566770a9e1eb7e07b8dd3b1e717 Mon Sep 17 00:00:00 2001 From: Robin Aggleton Date: Tue, 16 Oct 2018 12:33:55 +0200 Subject: MAINT: fix depreciation message typo for np.sum --- 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 81a1a66b7..b189dae5f 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2061,7 +2061,7 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._No # 2018-02-25, 1.15.0 warnings.warn( "Calling np.sum(generator) is deprecated, and in the future will give a different result. " - "Use np.sum(np.from_iter(generator)) or the python sum builtin instead.", + "Use np.sum(np.fromiter(generator)) or the python sum builtin instead.", DeprecationWarning, stacklevel=2) res = _sum_(a) -- cgit v1.2.1 From 7e0d3fe31ed6a31ff08fb1fc0c9e6c0e1f6a8568 Mon Sep 17 00:00:00 2001 From: tteichmann <44259103+tteichmann@users.noreply.github.com> Date: Fri, 19 Oct 2018 17:38:44 +0200 Subject: DOC: Clarify the examples for argmax and argmin (#12211) --- numpy/core/fromnumeric.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index b189dae5f..2fdbf3e23 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1071,10 +1071,10 @@ def argmax(a, axis=None, out=None): Examples -------- - >>> a = np.arange(6).reshape(2,3) + >>> a = np.arange(6).reshape(2,3) + 10 >>> a - array([[0, 1, 2], - [3, 4, 5]]) + array([[10, 11, 12], + [13, 14, 15]]) >>> np.argmax(a) 5 >>> np.argmax(a, axis=0) @@ -1088,7 +1088,7 @@ def argmax(a, axis=None, out=None): >>> ind (1, 2) >>> a[ind] - 5 + 15 >>> b = np.arange(6) >>> b[1] = 5 @@ -1140,10 +1140,10 @@ def argmin(a, axis=None, out=None): Examples -------- - >>> a = np.arange(6).reshape(2,3) + >>> a = np.arange(6).reshape(2,3) + 10 >>> a - array([[0, 1, 2], - [3, 4, 5]]) + array([[10, 11, 12], + [13, 14, 15]]) >>> np.argmin(a) 0 >>> np.argmin(a, axis=0) @@ -1157,12 +1157,12 @@ def argmin(a, axis=None, out=None): >>> ind (0, 0) >>> a[ind] - 0 + 10 - >>> b = np.arange(6) - >>> b[4] = 0 + >>> b = np.arange(6) + 10 + >>> b[4] = 10 >>> b - array([0, 1, 2, 3, 0, 5]) + array([10, 11, 12, 13, 10, 15]) >>> np.argmin(b) # Only the first occurrence is returned. 0 -- cgit v1.2.1 From 8bab96faf2cb740536712e49e92e133626087018 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Tue, 23 Oct 2018 07:53:58 -0700 Subject: MAINT: set preferred __module__ for numpy functions --- numpy/core/fromnumeric.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 2fdbf3e23..7dfb52fea 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -3,16 +3,17 @@ """ from __future__ import division, absolute_import, print_function +import functools import types import warnings import numpy as np from .. import VisibleDeprecationWarning 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 .overrides import array_function_dispatch from . import _methods _dt_ = nt.sctype2char @@ -32,6 +33,9 @@ _gentype = types.GeneratorType # save away Python sum _sum_ = sum +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + # functions that are now methods def _wrapit(obj, method, *args, **kwds): -- cgit v1.2.1 From 0ee245bc6df60b911fafe81a743ec2a68a063c20 Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Sat, 1 Dec 2018 19:03:55 +0100 Subject: MAINT: Use list and dict comprehension when possible (#12445) * Use list comprehension * More list comprehension migration * Revert key copying in dict * A few more fixes * More reverts * Use dict comprehension * Fix dict comprehension * Address review comments * More review comments * Fix for empty unpacking of zip(* * Revert zip(* unpacking altogether * Fix dict copying * More simplifications --- numpy/core/fromnumeric.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 7dfb52fea..59a820d53 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -67,10 +67,8 @@ def _wrapfunc(obj, method, *args, **kwds): def _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs): - passkwargs = {} - for k, v in kwargs.items(): - if v is not np._NoValue: - passkwargs[k] = v + passkwargs = {k: v for k, v in kwargs.items() + if v is not np._NoValue} if type(obj) is not mu.ndarray: try: -- cgit v1.2.1 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