summaryrefslogtreecommitdiff
path: root/numpy/lib/function_base.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/lib/function_base.py')
-rw-r--r--numpy/lib/function_base.py386
1 files changed, 40 insertions, 346 deletions
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 17f99a065..9336579af 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -1,15 +1,14 @@
from __future__ import division, absolute_import, print_function
__docformat__ = "restructuredtext en"
-__all__ = ['select', 'piecewise', 'trim_zeros', 'copy', 'iterable',
- 'percentile', 'diff', 'gradient', 'angle', 'unwrap', 'sort_complex',
- 'disp', 'extract', 'place', 'nansum', 'nanmax', 'nanargmax',
- 'nanargmin', 'nanmin', 'vectorize', 'asarray_chkfinite', 'average',
- 'histogram', 'histogramdd', 'bincount', 'digitize', 'cov',
- 'corrcoef', 'msort', 'median', 'sinc', 'hamming', 'hanning',
- 'bartlett', 'blackman', 'kaiser', 'trapz', 'i0', 'add_newdoc',
- 'add_docstring', 'meshgrid', 'delete', 'insert', 'append', 'interp',
- 'add_newdoc_ufunc']
+__all__ = [
+ 'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile',
+ 'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp',
+ 'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average',
+ 'histogram', 'histogramdd', 'bincount', 'digitize', 'cov', 'corrcoef',
+ 'msort', 'median', 'sinc', 'hamming', 'hanning', 'bartlett',
+ 'blackman', 'kaiser', 'trapz', 'i0', 'add_newdoc', 'add_docstring',
+ 'meshgrid', 'delete', 'insert', 'append', 'interp', 'add_newdoc_ufunc']
import warnings
import types
@@ -22,7 +21,7 @@ from numpy.core.numeric import ScalarType, dot, where, newaxis, intp, \
integer, isscalar
from numpy.core.umath import pi, multiply, add, arctan2, \
frompyfunc, isnan, cos, less_equal, sqrt, sin, mod, exp, log10
-from numpy.core.fromnumeric import ravel, nonzero, choose, sort, mean
+from numpy.core.fromnumeric import ravel, nonzero, choose, sort, partition, mean
from numpy.core.numerictypes import typecodes, number
from numpy.core import atleast_1d, atleast_2d
from numpy.lib.twodim_base import diag
@@ -1361,331 +1360,6 @@ def place(arr, mask, vals):
"""
return _insert(arr, mask, vals)
-def _nanop(op, fill, a, axis=None):
- """
- General operation on arrays with not-a-number values.
-
- Parameters
- ----------
- op : callable
- Operation to perform.
- fill : float
- NaN values are set to fill before doing the operation.
- a : array-like
- Input array.
- axis : {int, None}, optional
- Axis along which the operation is computed.
- By default the input is flattened.
-
- Returns
- -------
- y : {ndarray, scalar}
- Processed data.
-
- """
- y = array(a, subok=True)
-
- # We only need to take care of NaN's in floating point arrays
- dt = y.dtype
- if np.issubdtype(dt, np.integer) or np.issubdtype(dt, np.bool_):
- return op(y, axis=axis)
-
- mask = isnan(a)
- # y[mask] = fill
- # We can't use fancy indexing here as it'll mess w/ MaskedArrays
- # Instead, let's fill the array directly...
- np.copyto(y, fill, where=mask)
- res = op(y, axis=axis)
- mask_all_along_axis = mask.all(axis=axis)
-
- # Along some axes, only nan's were encountered. As such, any values
- # calculated along that axis should be set to nan.
- if mask_all_along_axis.any():
- if np.isscalar(res):
- res = np.nan
- else:
- res[mask_all_along_axis] = np.nan
-
- return res
-
-def nansum(a, axis=None):
- """
- Return the sum of array elements over a given axis treating
- Not a Numbers (NaNs) as zero.
-
- Parameters
- ----------
- a : array_like
- Array containing numbers whose sum is desired. If `a` is not an
- array, a conversion is attempted.
- axis : int, optional
- Axis along which the sum is computed. The default is to compute
- the sum of the flattened array.
-
- Returns
- -------
- y : ndarray
- An array with the same shape as a, with the specified axis removed.
- If a is a 0-d array, or if axis is None, a scalar is returned with
- the same dtype as `a`.
-
- See Also
- --------
- numpy.sum : Sum across array including Not a Numbers.
- isnan : Shows which elements are Not a Number (NaN).
- isfinite: Shows which elements are not: Not a Number, positive and
- negative infinity
-
- Notes
- -----
- Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
- (IEEE 754). This means that Not a Number is not equivalent to infinity.
- If positive or negative infinity are present the result is positive or
- negative infinity. But if both positive and negative infinity are present,
- the result is Not A Number (NaN).
-
- Arithmetic is modular when using integer types (all elements of `a` must
- be finite i.e. no elements that are NaNs, positive infinity and negative
- infinity because NaNs are floating point types), and no error is raised
- on overflow.
-
-
- Examples
- --------
- >>> np.nansum(1)
- 1
- >>> np.nansum([1])
- 1
- >>> np.nansum([1, np.nan])
- 1.0
- >>> a = np.array([[1, 1], [1, np.nan]])
- >>> np.nansum(a)
- 3.0
- >>> np.nansum(a, axis=0)
- array([ 2., 1.])
-
- When positive infinity and negative infinity are present
-
- >>> np.nansum([1, np.nan, np.inf])
- inf
- >>> np.nansum([1, np.nan, np.NINF])
- -inf
- >>> np.nansum([1, np.nan, np.inf, np.NINF])
- nan
-
- """
- return _nanop(np.sum, 0, a, axis)
-
-def nanmin(a, axis=None):
- """
- Return the minimum of an array or minimum along an axis, ignoring any NaNs.
-
- Parameters
- ----------
- a : array_like
- Array containing numbers whose minimum is desired. If `a` is not
- an array, a conversion is attempted.
- axis : int, optional
- Axis along which the minimum is computed. The default is to compute
- the minimum of the flattened array.
-
- Returns
- -------
- nanmin : ndarray
- An array with the same shape as `a`, with the specified axis removed.
- If `a` is a 0-d array, or if axis is None, an ndarray scalar is
- returned. The same dtype as `a` is returned.
-
- See Also
- --------
- nanmax :
- The maximum value of an array along a given axis, ignoring any NaNs.
- amin :
- The minimum value of an array along a given axis, propagating any NaNs.
- fmin :
- Element-wise minimum of two arrays, ignoring any NaNs.
- minimum :
- Element-wise minimum of two arrays, propagating any NaNs.
- isnan :
- Shows which elements are Not a Number (NaN).
- isfinite:
- Shows which elements are neither NaN nor infinity.
-
- amax, fmax, maximum
-
- Notes
- -----
- Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
- (IEEE 754). This means that Not a Number is not equivalent to infinity.
- Positive infinity is treated as a very large number and negative infinity
- is treated as a very small (i.e. negative) number.
-
- If the input has a integer type the function is equivalent to np.min.
-
- Examples
- --------
- >>> a = np.array([[1, 2], [3, np.nan]])
- >>> np.nanmin(a)
- 1.0
- >>> np.nanmin(a, axis=0)
- array([ 1., 2.])
- >>> np.nanmin(a, axis=1)
- array([ 1., 3.])
-
- When positive infinity and negative infinity are present:
-
- >>> np.nanmin([1, 2, np.nan, np.inf])
- 1.0
- >>> np.nanmin([1, 2, np.nan, np.NINF])
- -inf
-
- """
- a = np.asanyarray(a)
- if axis is not None:
- return np.fmin.reduce(a, axis)
- else:
- return np.fmin.reduce(a.flat)
-
-def nanargmin(a, axis=None):
- """
- Return indices of the minimum values over an axis, ignoring NaNs.
-
- Parameters
- ----------
- a : array_like
- Input data.
- axis : int, optional
- Axis along which to operate. By default flattened input is used.
-
- Returns
- -------
- index_array : ndarray
- An array of indices or a single index value.
-
- See Also
- --------
- argmin, nanargmax
-
- Examples
- --------
- >>> a = np.array([[np.nan, 4], [2, 3]])
- >>> np.argmin(a)
- 0
- >>> np.nanargmin(a)
- 2
- >>> np.nanargmin(a, axis=0)
- array([1, 1])
- >>> np.nanargmin(a, axis=1)
- array([1, 0])
-
- """
- return _nanop(np.argmin, np.inf, a, axis)
-
-def nanmax(a, axis=None):
- """
- Return the maximum of an array or maximum along an axis, ignoring any NaNs.
-
- Parameters
- ----------
- a : array_like
- Array containing numbers whose maximum is desired. If `a` is not
- an array, a conversion is attempted.
- axis : int, optional
- Axis along which the maximum is computed. The default is to compute
- the maximum of the flattened array.
-
- Returns
- -------
- nanmax : ndarray
- An array with the same shape as `a`, with the specified axis removed.
- If `a` is a 0-d array, or if axis is None, an ndarray scalar is
- returned. The same dtype as `a` is returned.
-
- See Also
- --------
- nanmin :
- The minimum value of an array along a given axis, ignoring any NaNs.
- amax :
- The maximum value of an array along a given axis, propagating any NaNs.
- fmax :
- Element-wise maximum of two arrays, ignoring any NaNs.
- maximum :
- Element-wise maximum of two arrays, propagating any NaNs.
- isnan :
- Shows which elements are Not a Number (NaN).
- isfinite:
- Shows which elements are neither NaN nor infinity.
-
- amin, fmin, minimum
-
- Notes
- -----
- Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
- (IEEE 754). This means that Not a Number is not equivalent to infinity.
- Positive infinity is treated as a very large number and negative infinity
- is treated as a very small (i.e. negative) number.
-
- If the input has a integer type the function is equivalent to np.max.
-
- Examples
- --------
- >>> a = np.array([[1, 2], [3, np.nan]])
- >>> np.nanmax(a)
- 3.0
- >>> np.nanmax(a, axis=0)
- array([ 3., 2.])
- >>> np.nanmax(a, axis=1)
- array([ 2., 3.])
-
- When positive infinity and negative infinity are present:
-
- >>> np.nanmax([1, 2, np.nan, np.NINF])
- 2.0
- >>> np.nanmax([1, 2, np.nan, np.inf])
- inf
-
- """
- a = np.asanyarray(a)
- if axis is not None:
- return np.fmax.reduce(a, axis)
- else:
- return np.fmax.reduce(a.flat)
-
-def nanargmax(a, axis=None):
- """
- Return indices of the maximum values over an axis, ignoring NaNs.
-
- Parameters
- ----------
- a : array_like
- Input data.
- axis : int, optional
- Axis along which to operate. By default flattened input is used.
-
- Returns
- -------
- index_array : ndarray
- An array of indices or a single index value.
-
- See Also
- --------
- argmax, nanargmin
-
- Examples
- --------
- >>> a = np.array([[np.nan, 4], [2, 3]])
- >>> np.argmax(a)
- 0
- >>> np.nanargmax(a)
- 1
- >>> np.nanargmax(a, axis=0)
- array([1, 0])
- >>> np.nanargmax(a, axis=1)
- array([1, 1])
-
- """
- return _nanop(np.argmax, -np.inf, a, axis)
-
def disp(mesg, device=None, linefeed=True):
"""
Display a message on a device.
@@ -2996,30 +2670,50 @@ def median(a, axis=None, out=None, overwrite_input=False):
>>> assert not np.all(a==b)
"""
+ if axis is not None and axis >= a.ndim:
+ raise IndexError("axis %d out of bounds (%d)" % (axis, a.ndim))
+
if overwrite_input:
if axis is None:
- sorted = a.ravel()
- sorted.sort()
+ part = a.ravel()
+ sz = part.size
+ if sz % 2 == 0:
+ szh = sz // 2
+ part.partition((szh - 1, szh))
+ else:
+ part.partition((sz - 1) // 2)
else:
- a.sort(axis=axis)
- sorted = a
+ sz = a.shape[axis]
+ if sz % 2 == 0:
+ szh = sz // 2
+ a.partition((szh - 1, szh), axis=axis)
+ else:
+ a.partition((sz - 1) // 2, axis=axis)
+ part = a
else:
- sorted = sort(a, axis=axis)
- if sorted.shape == ():
+ if axis is None:
+ sz = a.size
+ else:
+ sz = a.shape[axis]
+ if sz % 2 == 0:
+ part = partition(a, ((sz // 2) - 1, sz // 2), axis=axis)
+ else:
+ part = partition(a, (sz - 1) // 2, axis=axis)
+ if part.shape == ():
# make 0-D arrays work
- return sorted.item()
+ return part.item()
if axis is None:
axis = 0
- indexer = [slice(None)] * sorted.ndim
- index = int(sorted.shape[axis]/2)
- if sorted.shape[axis] % 2 == 1:
+ indexer = [slice(None)] * part.ndim
+ index = part.shape[axis] // 2
+ if part.shape[axis] % 2 == 1:
# index with slice to allow mean (below) to work
indexer[axis] = slice(index, index+1)
else:
indexer[axis] = slice(index-1, index+1)
# Use mean in odd and even case to coerce data type
# and check, use out array.
- return mean(sorted[indexer], axis=axis, out=out)
+ return mean(part[indexer], axis=axis, out=out)
def percentile(a, q, axis=None, out=None, overwrite_input=False):
"""