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 From 12fb1015511ac3804d0785bb0d1fe539385548ad Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Fri, 10 May 2019 19:14:35 -0700 Subject: ENH: Radix sort --- numpy/core/fromnumeric.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index b4d721940..7024ac237 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -824,7 +824,7 @@ def _sort_dispatcher(a, axis=None, kind=None, order=None): @array_function_dispatch(_sort_dispatcher) -def sort(a, axis=-1, kind='quicksort', order=None): +def sort(a, axis=-1, kind=None, order=None): """ Return a sorted copy of an array. @@ -837,8 +837,8 @@ def sort(a, axis=-1, kind='quicksort', order=None): sorting. The default is -1, which sorts along the last axis. kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional Sorting algorithm. The default is 'quicksort'. Note that both 'stable' - and 'mergesort' use timsort under the covers and, in general, the - actual implementation will vary with data type. The 'mergesort' option + and 'mergesort' use timsort or radix sort under the covers and, in general, + the actual implementation will vary with data type. The 'mergesort' option is retained for backwards compatibility. .. versionchanged:: 1.15.0. @@ -914,7 +914,8 @@ def sort(a, axis=-1, kind='quicksort', order=None): 'stable' automatically choses the best stable sorting algorithm for the data type being sorted. It, along with 'mergesort' is - currently mapped to timsort. API forward compatibility currently limits the + currently mapped to timsort or radix sort depending on the + data type. API forward compatibility currently limits the ability to select the implementation and it is hardwired for the different data types. @@ -925,7 +926,8 @@ def sort(a, axis=-1, kind='quicksort', order=None): mergesort. It is now used for stable sort while quicksort is still the default sort if none is chosen. For details of timsort, refer to `CPython listsort.txt `_. - + 'mergesort' and 'stable' are mapped to radix sort for integer data types. Radix sort is an + O(n) sort instead of O(n log n). Examples -------- @@ -974,7 +976,7 @@ def _argsort_dispatcher(a, axis=None, kind=None, order=None): @array_function_dispatch(_argsort_dispatcher) -def argsort(a, axis=-1, kind='quicksort', order=None): +def argsort(a, axis=-1, kind=None, order=None): """ Returns the indices that would sort an array. @@ -997,8 +999,6 @@ def argsort(a, axis=-1, kind='quicksort', order=None): .. versionchanged:: 1.15.0. The 'stable' option was added. - - order : str or list of str, optional When `a` is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can -- cgit v1.2.1 From dfe7b9db2350505903ba19867bf27dabda2bff71 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sun, 9 Dec 2018 01:08:33 -0800 Subject: ENH/DEP: Use a ufunc under the hood for ndarray.clip This includes: * The addition of 3-input PyObject inner loop * The removal of `->f->fastclip` for builtin types, which now use ufuncs instead * A deprecation in `PyArray_Clip` for third-party types that still use `->f->fastclip` * A deprecation of the unusual casting behavior of `clip` * A deprecation of the broken `nan`-behavior of `clip`, which was previously dependent on dimensionality and byte-order. --- numpy/core/fromnumeric.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 7024ac237..814ade64e 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1961,12 +1961,12 @@ def compress(condition, a, axis=None, out=None): return _wrapfunc(a, 'compress', condition, axis=axis, out=out) -def _clip_dispatcher(a, a_min, a_max, out=None): +def _clip_dispatcher(a, a_min, a_max, out=None, **kwargs): return (a, a_min, a_max) @array_function_dispatch(_clip_dispatcher) -def clip(a, a_min, a_max, out=None): +def clip(a, a_min, a_max, out=None, **kwargs): """ Clip (limit) the values in an array. @@ -1992,6 +1992,11 @@ def clip(a, a_min, a_max, out=None): The results will be placed in this array. It may be the input array for in-place clipping. `out` must be of the right shape to hold the output. Its type is preserved. + **kwargs + For other keyword-only arguments, see the + :ref:`ufunc docs `. + + .. versionadded:: 1.17.0 Returns ------- @@ -2020,7 +2025,7 @@ def clip(a, a_min, a_max, out=None): array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - return _wrapfunc(a, 'clip', a_min, a_max, out=out) + return _wrapfunc(a, 'clip', a_min, a_max, out=out, **kwargs) def _sum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, -- cgit v1.2.1 From 6492f632a92439c82c74efa6753e10ce9360c6ba Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Mon, 4 Mar 2019 19:27:47 -0800 Subject: MAINT: address reviewer comments * Unit test for object clip issue * parametrized test_simple_int32_inout() to additionally handle scenario where "unsafe" casting is explicitly passed through, as requested by reviewer * add a requested comment related to possibility of future nan check optimization for `@name@_clip` * add a unit test to cover the case where np.clip() is called with None for both max and min * add a unit test for the case where out is None and casting is specified as an invalid value, to flush through code path in TestClip.fastclip * add unit test + doc update for expected behavior when amin > amax * add unit test + patch for bug in npy_ObjectClip; its operations and operands were wrong; the unit test case is based on a scenario probed by the hypothesis library * add unit test for error in timedelta64 MAX function for clip handling * add unit test for a pathological case where np.ones(10) is clipped with amin=1, amax=0 --- numpy/core/fromnumeric.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 814ade64e..58da8a54b 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1975,6 +1975,9 @@ def clip(a, a_min, a_max, out=None, **kwargs): is specified, values smaller than 0 become 0, and values larger than 1 become 1. + Equivalent to but faster than ``np.maximum(a_min, np.minimum(a, a_max))``. + No check is performed to ensure ``a_min < a_max``. + Parameters ---------- a : array_like -- cgit v1.2.1 From 0ca5969ae7dcd1770f117d8c8782b7c4ec4e5ca4 Mon Sep 17 00:00:00 2001 From: John Belmonte Date: Thu, 16 May 2019 11:37:53 +0900 Subject: searchsorted: remove performance claim Fixes #13566 --- numpy/core/fromnumeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 58da8a54b..a5d27a008 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1279,7 +1279,7 @@ def searchsorted(a, v, side='left', sorter=None): As of NumPy 1.4.0 `searchsorted` works with real/complex arrays containing `nan` values. The enhanced sort order is documented in `sort`. - This function is a faster version of the builtin python `bisect.bisect_left` + This function is a version of the builtin python `bisect.bisect_left` (``side='left'``) and `bisect.bisect_right` (``side='right'``) functions, which is also vectorized in the `v` argument. -- cgit v1.2.1 From f9c1502e7ace9b48f0256a77c560aae43763a1f2 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Mon, 20 May 2019 09:37:18 -0700 Subject: BUG: Increment stacklevel for warnings to account for NEP-18 overrides (#13589) * Increment stacklevel for warnings to account for NEP-18 overrides For NumPy functions that make use of `__array_function__`, the appropriate the stack level for warnings should generally be increased by 1 to account for the override function defined in numpy.core.overrides. Fixes GH-13329 * Update numpy/lib/type_check.py Co-Authored-By: Sebastian Berg --- numpy/core/fromnumeric.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 58da8a54b..cbbee463a 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2145,7 +2145,7 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, warnings.warn( "Calling np.sum(generator) is deprecated, and in the future will give a different result. " "Use np.sum(np.fromiter(generator)) or the python sum builtin instead.", - DeprecationWarning, stacklevel=2) + DeprecationWarning, stacklevel=3) res = _sum_(a) if out is not None: @@ -3569,5 +3569,5 @@ def rank(a): warnings.warn( "`rank` is deprecated; use the `ndim` attribute or function instead. " "To find the rank of a matrix see `numpy.linalg.matrix_rank`.", - VisibleDeprecationWarning, stacklevel=2) + VisibleDeprecationWarning, stacklevel=3) return ndim(a) -- cgit v1.2.1 From 966ccea02bd3f9f8fa7fffb8c2903ff2daf83b58 Mon Sep 17 00:00:00 2001 From: John Belmonte Date: Wed, 22 May 2019 21:21:43 +0900 Subject: change wording --- numpy/core/fromnumeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index a5d27a008..b81a4fa05 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1279,7 +1279,7 @@ def searchsorted(a, v, side='left', sorter=None): As of NumPy 1.4.0 `searchsorted` works with real/complex arrays containing `nan` values. The enhanced sort order is documented in `sort`. - This function is a version of the builtin python `bisect.bisect_left` + This function uses the same algorithm as the builtin python `bisect.bisect_left` (``side='left'``) and `bisect.bisect_right` (``side='right'``) functions, which is also vectorized in the `v` argument. -- cgit v1.2.1 From 1f427353554e6403f87c01f81b6e414427faa5f0 Mon Sep 17 00:00:00 2001 From: Abhinav Sagar <40603139+abhinavsagar@users.noreply.github.com> Date: Wed, 29 May 2019 10:43:35 +0530 Subject: DOC: Add note to ``nonzero`` docstring. (#13551) * Added NOTE in numpy\core\fromnumeric.py --- numpy/core/fromnumeric.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 202802e2c..af2a5298d 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1795,6 +1795,11 @@ def nonzero(a): Equivalent ndarray method. count_nonzero : Counts the number of non-zero elements in the input array. + + Notes + ----- + To obtain the non-zero values, it is recommended to use ``x[x.astype(bool)]`` + which will correctly handle 0-d arrays. Examples -------- -- cgit v1.2.1 From dcf9d9628eb50d275a6d42a6ed2cfdd25949ef57 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Fri, 7 Jun 2019 11:18:16 +0300 Subject: DOC: emphasize that nonzero is a bad idea on 0d arrays Also indicate that the current behavior in this case is deprecated. This also removes the advice to use `a[nonzero(a)]` or `transpose(nonzero(a))`, for which there are better spellings. --- numpy/core/fromnumeric.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index af2a5298d..d78cdf365 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1764,17 +1764,17 @@ def nonzero(a): Returns a tuple of arrays, one for each dimension of `a`, containing the indices of the non-zero elements in that dimension. The values in `a` are always tested and returned in - row-major, C-style order. The corresponding non-zero - values can be obtained with:: + row-major, C-style order. - a[nonzero(a)] + To group the indices by element, rather than dimension, use `argwhere`, + which returns a row for each non-zero element. - To group the indices by element, rather than dimension, use:: - - transpose(nonzero(a)) + .. note:: + When called on a zero-d array or scalar, ``nonzero(a)`` is treated + as ``nonzero(atleast1d(a))``. - The result of this is always a 2-D array, with a row for - each non-zero element. + ..deprecated:: 1.17.0 + Use `atleast1d` explicitly if this behavior is deliberate. Parameters ---------- @@ -1795,11 +1795,12 @@ def nonzero(a): Equivalent ndarray method. count_nonzero : Counts the number of non-zero elements in the input array. - + Notes ----- - To obtain the non-zero values, it is recommended to use ``x[x.astype(bool)]`` - which will correctly handle 0-d arrays. + While the nonzero values can be obtained with ``a[nonzero(a)]``, it is + recommended to use ``x[x.astype(bool)]`` or ``x[x != 0]`` instead, which + will correctly handle 0-d arrays. Examples -------- -- cgit v1.2.1 From 871ed9b188da73bfed6386530e579e3287e9b3ed Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Tue, 11 Jun 2019 00:55:45 -0500 Subject: DOC: Mention and try to explain pairwise summation in sum (#13737) * DOC: Mention and try to explain pairwise summation in sum Note that this behaviour is of course inherited into `np.add.reduce` and many other reductions such as `mean` or users of this reduction, such as `cov`. This is ignored here. --- numpy/core/fromnumeric.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index af2a5298d..f262f8552 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2104,6 +2104,8 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, -------- ndarray.sum : Equivalent method. + add.reduce : Equivalent functionality of `add`. + cumsum : Cumulative sum of array elements. trapz : Integration of array values using the composite trapezoidal rule. @@ -2120,6 +2122,23 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, >>> np.sum([]) 0.0 + For floating point numbers the numerical precision of sum (and + ``np.add.reduce``) is in general limited by directly adding each number + individually to the result causing rounding errors in every step. + However, often numpy will use a numerically better approach (partial + pairwise summation) leading to improved precision in many use-cases. + This improved precision is always provided when no ``axis`` is given. + When ``axis`` is given, it will depend on which axis is summed. + Technically, to provide the best speed possible, the improved precision + is only used when the summation is along the fast axis in memory. + Note that the exact precision may vary depending on other parameters. + In contrast to NumPy, Python's ``math.fsum`` function uses a slower but + more precise approach to summation. + Especially when summing a large number of lower precision floating point + numbers, such as ``float32``, numerical errors can become significant. + In such cases it can be advisable to use `dtype="float64"` to use a higher + precision for the output. + Examples -------- >>> np.sum([0.5, 1.5]) -- cgit v1.2.1 From 5b0069c08d00e871d74c6533e0b0eeb3107e8f70 Mon Sep 17 00:00:00 2001 From: Jeff Hale Date: Sat, 13 Jul 2019 16:20:22 -0500 Subject: DOC: improve np.sort docstring (#13968) * improve language around sorting --- numpy/core/fromnumeric.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 08f17aae4..3389e7d66 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -908,14 +908,18 @@ def sort(a, axis=-1, kind=None, order=None): .. versionadded:: 1.12.0 - quicksort has been changed to an introsort which will switch - 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, along with 'mergesort' is - currently mapped to timsort or radix sort depending on the - data type. API forward compatibility currently limits the + quicksort has been changed to `introsort `_. + When sorting does not make enough progress it switches to + `heapsort `_. + This implementation makes quicksort O(n*log(n)) in the worst case. + + 'stable' automatically chooses the best stable sorting algorithm + for the data type being sorted. + It, along with 'mergesort' is currently mapped to + `timsort `_ + or `radix sort `_ + depending on the data type. + API forward compatibility currently limits the ability to select the implementation and it is hardwired for the different data types. @@ -924,7 +928,7 @@ def sort(a, axis=-1, kind=None, order=None): 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 - default sort if none is chosen. For details of timsort, refer to + default sort if none is chosen. For timsort details, refer to `CPython listsort.txt `_. 'mergesort' and 'stable' are mapped to radix sort for integer data types. Radix sort is an O(n) sort instead of O(n log n). -- cgit v1.2.1 From f483ad1f7fd3868fb2138afdb11f67063e149cf5 Mon Sep 17 00:00:00 2001 From: Samesh Date: Wed, 17 Jul 2019 19:31:22 +0530 Subject: DEP: Remove np.rank which has been deprecated for more than 5 years references #7059 --- numpy/core/fromnumeric.py | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 3389e7d66..75a6bae7f 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -25,7 +25,7 @@ __all__ = [ 'argmin', 'argpartition', 'argsort', 'around', 'choose', 'clip', 'compress', 'cumprod', 'cumproduct', 'cumsum', 'diagonal', 'mean', 'ndim', 'nonzero', 'partition', 'prod', 'product', 'ptp', 'put', - 'rank', 'ravel', 'repeat', 'reshape', 'resize', 'round_', + 'ravel', 'repeat', 'reshape', 'resize', 'round_', 'searchsorted', 'shape', 'size', 'sometrue', 'sort', 'squeeze', 'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var', ] @@ -3573,30 +3573,3 @@ def alltrue(*args, **kwargs): numpy.all : Equivalent function; see for details. """ return all(*args, **kwargs) - - -@array_function_dispatch(_ndim_dispatcher) -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=3) - return ndim(a) -- cgit v1.2.1 From 68626acba30ab59fa1ef27c25eb7ed93f227396e Mon Sep 17 00:00:00 2001 From: Guilherme Leobas Date: Thu, 8 Aug 2019 08:31:42 -0300 Subject: DEP: Deprecate np.alen (#14181) * Deprecate and fix tests for alen --- numpy/core/fromnumeric.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 75a6bae7f..c9ea44425 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -2782,6 +2782,10 @@ def alen(a): 7 """ + # NumPy 1.18.0, 2019-08-02 + warnings.warn( + "`np.alen` is deprecated, use `len` instead", + DeprecationWarning, stacklevel=2) try: return len(a) except TypeError: -- cgit v1.2.1 From 4d734a4e6ef29d1f26a00b515f5f892ccdaf7ef9 Mon Sep 17 00:00:00 2001 From: colinsnyder <47012605+colinsnyder@users.noreply.github.com> Date: Thu, 15 Aug 2019 01:48:50 -0700 Subject: DOC: mention `take_along_axis` in `choose` (#14224) * DOC: mention take_along_axis in choose --- 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 c9ea44425..bde37fca3 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -380,6 +380,7 @@ def choose(a, choices, out=None, mode='raise'): See Also -------- ndarray.choose : equivalent method + numpy.take_along_axis : Preferable if `choices` is an array Notes ----- @@ -908,17 +909,17 @@ def sort(a, axis=-1, kind=None, order=None): .. versionadded:: 1.12.0 - quicksort has been changed to `introsort `_. + quicksort has been changed to `introsort `_. When sorting does not make enough progress it switches to - `heapsort `_. + `heapsort `_. This implementation makes quicksort O(n*log(n)) in the worst case. 'stable' automatically chooses the best stable sorting algorithm - for the data type being sorted. - It, along with 'mergesort' is currently mapped to - `timsort `_ - or `radix sort `_ - depending on the data type. + for the data type being sorted. + It, along with 'mergesort' is currently mapped to + `timsort `_ + or `radix sort `_ + depending on the data type. API forward compatibility currently limits the ability to select the implementation and it is hardwired for the different data types. -- cgit v1.2.1 From 8c0bb22cb5b0979defe11e4befd20f7b79f5da08 Mon Sep 17 00:00:00 2001 From: Isaac Virshup Date: Tue, 27 Aug 2019 12:32:52 +1000 Subject: DOC: Fixed dtype docs for var, nanvar. Docs incorrectly stated that the default output dtype was float32 when input array is of an integer dtype. However: ```python np.var(np.random.randint(0, 100, 1000)).dtype == np.dtype("f8") ``` --- 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 08f17aae4..c37dbc5df 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -3410,7 +3410,7 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): instead of a single axis or all the axes as before. dtype : data-type, optional Type to use in computing the variance. For arrays of integer type - the default is `float32`; for arrays of float types it is the same as + the default is `float64`; for arrays of float types it is the same as the array type. out : ndarray, optional Alternate output array in which to place the result. It must have -- cgit v1.2.1 From 2ca7ea980fbf0fa8753c3040f332fef82d963e3a Mon Sep 17 00:00:00 2001 From: Allan Haldane Date: Wed, 28 Aug 2019 11:40:58 -0400 Subject: DOC: update np.around docstring with note about floating-point error Fixes #14391 [ci-skip] --- numpy/core/fromnumeric.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 3314e516e..422ebe2de 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -3125,10 +3125,35 @@ def around(a, decimals=0, out=None): ----- For values exactly halfway between rounded decimal values, NumPy rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0, - -0.5 and 0.5 round to 0.0, etc. Results may also be surprising due - to the inexact representation of decimal fractions in the IEEE - floating point standard [1]_ and errors introduced when scaling - by powers of ten. + -0.5 and 0.5 round to 0.0, etc. + + ``np.around`` uses a fast but sometimes inexact algorithm to round + floating-point datatypes. For positive `decimals` it is equivalent to + ``np.true_divide(np.rint(a * 10**decimals), 10**decimals)``, which is + inexact for large floating-point values or large values of `decimals` due + the inexact representation of decimal fractions in the IEEE floating point + standard [1]_ and errors introduced when scaling by powers of ten. For + instance, note the extra "1" in the following: + + >>> np.round(56294995342131.5, 3) + 56294995342131.51 + + If your goal is to print such values with a fixed number of decimals, it is + preferable to use numpy's float printing routines to limit the number of + printed decimals: + + >>> np.format_float_positional(56294995342131.5, precision=3) + '56294995342131.5' + + The float printing routines use an accurate but much more computationally + demanding algorithm to compute the number of digits after the decimal + point. + + Alternatively, Python's builtin `round` function uses a more accurate + but slower algorithm for 64-bit floating point values: + + >>> round(56294995342131.5, 3) + 56294995342131.5 References ---------- -- cgit v1.2.1 From d6d9fafe4f386caea7afd48b6a5774108bfcf577 Mon Sep 17 00:00:00 2001 From: Allan Haldane Date: Fri, 13 Sep 2019 18:42:43 -0400 Subject: DOC: tweak np.round docstring to clarify floating-point error --- numpy/core/fromnumeric.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 422ebe2de..140056432 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -3129,11 +3129,10 @@ def around(a, decimals=0, out=None): ``np.around`` uses a fast but sometimes inexact algorithm to round floating-point datatypes. For positive `decimals` it is equivalent to - ``np.true_divide(np.rint(a * 10**decimals), 10**decimals)``, which is - inexact for large floating-point values or large values of `decimals` due - the inexact representation of decimal fractions in the IEEE floating point - standard [1]_ and errors introduced when scaling by powers of ten. For - instance, note the extra "1" in the following: + ``np.true_divide(np.rint(a * 10**decimals), 10**decimals)``, which has + error due to the inexact representation of decimal fractions in the IEEE + floating point standard [1]_ and errors introduced when scaling by powers + of ten. For instance, note the extra "1" in the following: >>> np.round(56294995342131.5, 3) 56294995342131.51 @@ -3154,6 +3153,9 @@ def around(a, decimals=0, out=None): >>> round(56294995342131.5, 3) 56294995342131.5 + >>> np.round(16.055, 2), round(16.055, 2) # equals 16.0549999999999997 + (16.06, 16.05) + References ---------- -- cgit v1.2.1 From 3a99bfe2d3cc7dbb397c9ce6e819adc9dab9b4e8 Mon Sep 17 00:00:00 2001 From: "Joseph R. Fox-Rabinovitz" Date: Mon, 30 Sep 2019 22:59:23 -0400 Subject: DOC: Updated sphinx directive formatting --- numpy/core/fromnumeric.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 140056432..6c0b9cde9 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1775,11 +1775,13 @@ def nonzero(a): which returns a row for each non-zero element. .. note:: - When called on a zero-d array or scalar, ``nonzero(a)`` is treated - as ``nonzero(atleast1d(a))``. - ..deprecated:: 1.17.0 - Use `atleast1d` explicitly if this behavior is deliberate. + When called on a zero-d array or scalar, ``nonzero(a)`` is treated + as ``nonzero(atleast1d(a))``. + + .. deprecated:: 1.17.0 + + Use `atleast1d` explicitly if this behavior is deliberate. Parameters ---------- -- cgit v1.2.1