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.py474
1 files changed, 316 insertions, 158 deletions
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 63b191b07..f625bcb90 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -13,6 +13,7 @@ __all__ = [
import warnings
import sys
import collections
+import operator
import numpy as np
import numpy.core.numeric as _nx
@@ -20,7 +21,7 @@ from numpy.core import linspace, atleast_1d, atleast_2d
from numpy.core.numeric import (
ones, zeros, arange, concatenate, array, asarray, asanyarray, empty,
empty_like, ndarray, around, floor, ceil, take, ScalarType, dot, where,
- newaxis, intp, integer, isscalar
+ intp, integer, isscalar
)
from numpy.core.umath import (
pi, multiply, add, arctan2, frompyfunc, cos, less_equal, sqrt, sin,
@@ -256,22 +257,22 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
range : sequence, optional
A sequence of lower and upper bin edges to be used if the edges are
- not given explicitely in `bins`. Defaults to the minimum and maximum
+ not given explicitly in `bins`. Defaults to the minimum and maximum
values along each dimension.
normed : bool, optional
- If False, returns the number of samples in each bin. If True, returns
- the bin density, ie, the bin count divided by the bin hypervolume.
+ If False, returns the number of samples in each bin. If True,
+ returns the bin density ``bin_count / sample_count / bin_volume``.
weights : array_like (N,), optional
An array of values `w_i` weighing each sample `(x_i, y_i, z_i, ...)`.
- Weights are normalized to 1 if normed is True. If normed is False, the
- values of the returned histogram are equal to the sum of the weights
- belonging to the samples falling into each bin.
+ Weights are normalized to 1 if normed is True. If normed is False,
+ the values of the returned histogram are equal to the sum of the
+ weights belonging to the samples falling into each bin.
Returns
-------
H : ndarray
- The multidimensional histogram of sample x. See normed and weights for
- the different possible semantics.
+ The multidimensional histogram of sample x. See normed and weights
+ for the different possible semantics.
edges : list
A list of D arrays describing the bin edges for each dimension.
@@ -335,6 +336,11 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
smin[i] = smin[i] - .5
smax[i] = smax[i] + .5
+ # avoid rounding issues for comparisons when dealing with inexact types
+ if np.issubdtype(sample.dtype, np.inexact):
+ edge_dt = sample.dtype
+ else:
+ edge_dt = float
# Create edge arrays
for i in arange(D):
if isscalar(bins[i]):
@@ -343,9 +349,9 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
"Element at index %s in `bins` should be a positive "
"integer." % i)
nbin[i] = bins[i] + 2 # +2 for outlier bins
- edges[i] = linspace(smin[i], smax[i], nbin[i]-1)
+ edges[i] = linspace(smin[i], smax[i], nbin[i]-1, dtype=edge_dt)
else:
- edges[i] = asarray(bins[i], float)
+ edges[i] = asarray(bins[i], edge_dt)
nbin[i] = len(edges[i]) + 1 # +1 for outlier bins
dedges[i] = diff(edges[i])
if np.any(np.asarray(dedges[i]) <= 0):
@@ -373,10 +379,10 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
if not np.isinf(mindiff):
decimal = int(-log10(mindiff)) + 6
# Find which points are on the rightmost edge.
- on_edge = where(around(sample[:, i], decimal) ==
- around(edges[i][-1], decimal))[0]
+ not_smaller_than_edge = (sample[:, i] >= edges[i][-1])
+ on_edge = (around(sample[:, i], decimal) == around(edges[i][-1], decimal))
# Shift these points one bin to the left.
- Ncount[i][on_edge] -= 1
+ Ncount[i][where(on_edge & not_smaller_than_edge)[0]] -= 1
# Flattened histogram matrix (1D)
# Reshape is used so that overlarge arrays
@@ -650,7 +656,7 @@ def piecewise(x, condlist, funclist, *args, **kw):
The output is the same shape and type as x and is found by
calling the functions in `funclist` on the appropriate portions of `x`,
as defined by the boolean arrays in `condlist`. Portions not covered
- by any condition have undefined values.
+ by any condition have a default value of 0.
See Also
@@ -692,32 +698,24 @@ def piecewise(x, condlist, funclist, *args, **kw):
if (isscalar(condlist) or not (isinstance(condlist[0], list) or
isinstance(condlist[0], ndarray))):
condlist = [condlist]
- condlist = [asarray(c, dtype=bool) for c in condlist]
+ condlist = array(condlist, dtype=bool)
n = len(condlist)
- if n == n2 - 1: # compute the "otherwise" condition.
- totlist = condlist[0]
- for k in range(1, n):
- totlist |= condlist[k]
- condlist.append(~totlist)
- n += 1
- if (n != n2):
- raise ValueError(
- "function list and condition list must be the same")
- zerod = False
# This is a hack to work around problems with NumPy's
# handling of 0-d arrays and boolean indexing with
# numpy.bool_ scalars
+ zerod = False
if x.ndim == 0:
x = x[None]
zerod = True
- newcondlist = []
- for k in range(n):
- if condlist[k].ndim == 0:
- condition = condlist[k][None]
- else:
- condition = condlist[k]
- newcondlist.append(condition)
- condlist = newcondlist
+ if condlist.shape[-1] != 1:
+ condlist = condlist.T
+ if n == n2 - 1: # compute the "otherwise" condition.
+ totlist = np.logical_or.reduce(condlist, axis=0)
+ condlist = np.vstack([condlist, ~totlist])
+ n += 1
+ if (n != n2):
+ raise ValueError(
+ "function list and condition list must be the same")
y = zeros(x.shape, x.dtype)
for k in range(n):
@@ -770,29 +768,68 @@ def select(condlist, choicelist, default=0):
array([ 0, 1, 2, 0, 0, 0, 36, 49, 64, 81])
"""
- n = len(condlist)
- n2 = len(choicelist)
- if n2 != n:
+ # Check the size of condlist and choicelist are the same, or abort.
+ if len(condlist) != len(choicelist):
raise ValueError(
- "list of cases must be same length as list of conditions")
- choicelist = [default] + choicelist
- S = 0
- pfac = 1
- for k in range(1, n+1):
- S += k * pfac * asarray(condlist[k-1])
- if k < n:
- pfac *= (1-asarray(condlist[k-1]))
- # handle special case of a 1-element condition but
- # a multi-element choice
- if type(S) in ScalarType or max(asarray(S).shape) == 1:
- pfac = asarray(1)
- for k in range(n2+1):
- pfac = pfac + asarray(choicelist[k])
- if type(S) in ScalarType:
- S = S*ones(asarray(pfac).shape, type(S))
- else:
- S = S*ones(asarray(pfac).shape, S.dtype)
- return choose(S, tuple(choicelist))
+ 'list of cases must be same length as list of conditions')
+
+ # Now that the dtype is known, handle the deprecated select([], []) case
+ if len(condlist) == 0:
+ warnings.warn("select with an empty condition list is not possible"
+ "and will be deprecated",
+ DeprecationWarning)
+ return np.asarray(default)[()]
+
+ choicelist = [np.asarray(choice) for choice in choicelist]
+ choicelist.append(np.asarray(default))
+
+ # need to get the result type before broadcasting for correct scalar
+ # behaviour
+ dtype = np.result_type(*choicelist)
+
+ # Convert conditions to arrays and broadcast conditions and choices
+ # as the shape is needed for the result. Doing it seperatly optimizes
+ # for example when all choices are scalars.
+ condlist = np.broadcast_arrays(*condlist)
+ choicelist = np.broadcast_arrays(*choicelist)
+
+ # If cond array is not an ndarray in boolean format or scalar bool, abort.
+ deprecated_ints = False
+ for i in range(len(condlist)):
+ cond = condlist[i]
+ if cond.dtype.type is not np.bool_:
+ if np.issubdtype(cond.dtype, np.integer):
+ # A previous implementation accepted int ndarrays accidentally.
+ # Supported here deliberately, but deprecated.
+ condlist[i] = condlist[i].astype(bool)
+ deprecated_ints = True
+ else:
+ raise ValueError(
+ 'invalid entry in choicelist: should be boolean ndarray')
+
+ if deprecated_ints:
+ msg = "select condlists containing integer ndarrays is deprecated " \
+ "and will be removed in the future. Use `.astype(bool)` to " \
+ "convert to bools."
+ warnings.warn(msg, DeprecationWarning)
+
+ if choicelist[0].ndim == 0:
+ # This may be common, so avoid the call.
+ result_shape = condlist[0].shape
+ else:
+ result_shape = np.broadcast_arrays(condlist[0], choicelist[0])[0].shape
+
+ result = np.full(result_shape, choicelist[-1], dtype)
+
+ # Use np.copyto to burn each choicelist array onto result, using the
+ # corresponding condlist as a boolean mask. This is done in reverse
+ # order since the first choice should take precedence.
+ choicelist = choicelist[-2::-1]
+ condlist = condlist[::-1]
+ for choice, cond in zip(choicelist, condlist):
+ np.copyto(result, choice, where=cond)
+
+ return result
def copy(a, order='K'):
@@ -1101,7 +1138,7 @@ def interp(x, xp, fp, left=None, right=None):
-----
Does not check that the x-coordinate sequence `xp` is increasing.
If `xp` is not increasing, the results are nonsense.
- A simple check for increasingness is::
+ A simple check for increasing is::
np.all(np.diff(xp) > 0)
@@ -1578,20 +1615,22 @@ class vectorize(object):
The `vectorize` function is provided primarily for convenience, not for
performance. The implementation is essentially a for loop.
- If `otypes` is not specified, then a call to the function with the first
- argument will be used to determine the number of outputs. The results of
- this call will be cached if `cache` is `True` to prevent calling the
- function twice. However, to implement the cache, the original function
- must be wrapped which will slow down subsequent calls, so only do this if
- your function is expensive.
+ If `otypes` is not specified, then a call to the function with the
+ first argument will be used to determine the number of outputs. The
+ results of this call will be cached if `cache` is `True` to prevent
+ calling the function twice. However, to implement the cache, the
+ original function must be wrapped which will slow down subsequent
+ calls, so only do this if your function is expensive.
+
+ The new keyword argument interface and `excluded` argument support
+ further degrades performance.
- The new keyword argument interface and `excluded` argument support further
- degrades performance.
"""
def __init__(self, pyfunc, otypes='', doc=None, excluded=None,
cache=False):
self.pyfunc = pyfunc
self.cache = cache
+ self._ufunc = None # Caching to improve default performance
if doc is None:
self.__doc__ = pyfunc.__doc__
@@ -1615,9 +1654,6 @@ class vectorize(object):
excluded = set()
self.excluded = set(excluded)
- if self.otypes and not self.excluded:
- self._ufunc = None # Caching to improve default performance
-
def __call__(self, *args, **kwargs):
"""
Return arrays with the results of `pyfunc` broadcast (vectorized) over
@@ -1651,7 +1687,8 @@ class vectorize(object):
def _get_ufunc_and_otypes(self, func, args):
"""Return (ufunc, otypes)."""
# frompyfunc will fail if args is empty
- assert args
+ if not args:
+ raise ValueError('args can not be empty')
if self.otypes:
otypes = self.otypes
@@ -1810,9 +1847,11 @@ def cov(m, y=None, rowvar=1, bias=0, ddof=None):
"ddof must be integer")
# Handles complex arrays too
+ m = np.asarray(m)
if y is None:
dtype = np.result_type(m, np.float64)
else:
+ y = np.asarray(y)
dtype = np.result_type(m, y, np.float64)
X = array(m, ndmin=2, dtype=dtype)
@@ -1821,11 +1860,9 @@ def cov(m, y=None, rowvar=1, bias=0, ddof=None):
if rowvar:
N = X.shape[1]
axis = 0
- tup = (slice(None), newaxis)
else:
N = X.shape[0]
axis = 1
- tup = (newaxis, slice(None))
# check ddof
if ddof is None:
@@ -1842,7 +1879,7 @@ def cov(m, y=None, rowvar=1, bias=0, ddof=None):
y = array(y, copy=False, ndmin=2, dtype=dtype)
X = concatenate((X, y), axis)
- X -= X.mean(axis=1-axis)[tup]
+ X -= X.mean(axis=1-axis, keepdims=True)
if not rowvar:
return (dot(X.T, X.conj()) / fact).squeeze()
else:
@@ -1909,7 +1946,7 @@ def blackman(M):
"""
Return the Blackman window.
- The Blackman window is a taper formed by using the the first three
+ The Blackman window is a taper formed by using the first three
terms of a summation of cosines. It was designed to have close to the
minimal leakage possible. It is close to optimal, only slightly worse
than a Kaiser window.
@@ -2139,9 +2176,10 @@ def hanning(M):
.. math:: w(n) = 0.5 - 0.5cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
\\qquad 0 \\leq n \\leq M-1
- The Hanning was named for Julius van Hann, an Austrian meterologist. It is
- also known as the Cosine Bell. Some authors prefer that it be called a
- Hann window, to help avoid confusion with the very similar Hamming window.
+ The Hanning was named for Julius van Hann, an Austrian meteorologist.
+ It is also known as the Cosine Bell. Some authors prefer that it be
+ called a Hann window, to help avoid confusion with the very similar
+ Hamming window.
Most references to the Hanning window come from the signal processing
literature, where it is used as one of many windowing functions for
@@ -2238,9 +2276,9 @@ def hamming(M):
.. math:: w(n) = 0.54 - 0.46cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
\\qquad 0 \\leq n \\leq M-1
- The Hamming was named for R. W. Hamming, an associate of J. W. Tukey and
- is described in Blackman and Tukey. It was recommended for smoothing the
- truncated autocovariance function in the time domain.
+ The Hamming was named for R. W. Hamming, an associate of J. W. Tukey
+ and is described in Blackman and Tukey. It was recommended for
+ smoothing the truncated autocovariance function in the time domain.
Most references to the Hamming window come from the signal processing
literature, where it is used as one of many windowing functions for
smoothing values. It is also known as an apodization (which means
@@ -2420,11 +2458,11 @@ def i0(x):
Notes
-----
We use the algorithm published by Clenshaw [1]_ and referenced by
- Abramowitz and Stegun [2]_, for which the function domain is partitioned
- into the two intervals [0,8] and (8,inf), and Chebyshev polynomial
- expansions are employed in each interval. Relative error on the domain
- [0,30] using IEEE arithmetic is documented [3]_ as having a peak of 5.8e-16
- with an rms of 1.4e-16 (n = 30000).
+ Abramowitz and Stegun [2]_, for which the function domain is
+ partitioned into the two intervals [0,8] and (8,inf), and Chebyshev
+ polynomial expansions are employed in each interval. Relative error on
+ the domain [0,30] using IEEE arithmetic is documented [3]_ as having a
+ peak of 5.8e-16 with an rms of 1.4e-16 (n = 30000).
References
----------
@@ -2494,12 +2532,11 @@ def kaiser(M, beta):
where :math:`I_0` is the modified zeroth-order Bessel function.
- The Kaiser was named for Jim Kaiser, who discovered a simple approximation
- to the DPSS window based on Bessel functions.
- The Kaiser window is a very good approximation to the Digital Prolate
- Spheroidal Sequence, or Slepian window, which is the transform which
- maximizes the energy in the main lobe of the window relative to total
- energy.
+ The Kaiser was named for Jim Kaiser, who discovered a simple
+ approximation to the DPSS window based on Bessel functions. The Kaiser
+ window is a very good approximation to the Digital Prolate Spheroidal
+ Sequence, or Slepian window, which is the transform which maximizes the
+ energy in the main lobe of the window relative to total energy.
The Kaiser can approximate many other windows by varying the beta
parameter.
@@ -2609,8 +2646,8 @@ def sinc(x):
The name sinc is short for "sine cardinal" or "sinus cardinalis".
The sinc function is used in various signal processing applications,
- including in anti-aliasing, in the construction of a
- Lanczos resampling filter, and in interpolation.
+ including in anti-aliasing, in the construction of a Lanczos resampling
+ filter, and in interpolation.
For bandlimited interpolation of discrete-time signals, the ideal
interpolation kernel is proportional to the sinc function.
@@ -2692,7 +2729,67 @@ def msort(a):
return b
-def median(a, axis=None, out=None, overwrite_input=False):
+def _ureduce(a, func, **kwargs):
+ """
+ Internal Function.
+ Call `func` with `a` as first argument swapping the axes to use extended
+ axis on functions that don't support it natively.
+
+ Returns result and a.shape with axis dims set to 1.
+
+ Parameters
+ ----------
+ a : array_like
+ Input array or object that can be converted to an array.
+ func : callable
+ Reduction function Kapable of receiving an axis argument.
+ It is is called with `a` as first argument followed by `kwargs`.
+ kwargs : keyword arguments
+ additional keyword arguments to pass to `func`.
+
+ Returns
+ -------
+ result : tuple
+ Result of func(a, **kwargs) and a.shape with axis dims set to 1
+ which can be used to reshape the result to the same shape a ufunc with
+ keepdims=True would produce.
+
+ """
+ a = np.asanyarray(a)
+ axis = kwargs.get('axis', None)
+ if axis is not None:
+ keepdim = list(a.shape)
+ nd = a.ndim
+ try:
+ axis = operator.index(axis)
+ if axis >= nd or axis < -nd:
+ raise IndexError("axis %d out of bounds (%d)" % (axis, a.ndim))
+ keepdim[axis] = 1
+ except TypeError:
+ sax = set()
+ for x in axis:
+ if x >= nd or x < -nd:
+ raise IndexError("axis %d out of bounds (%d)" % (x, nd))
+ if x in sax:
+ raise ValueError("duplicate value in axis")
+ sax.add(x % nd)
+ keepdim[x] = 1
+ keep = sax.symmetric_difference(frozenset(range(nd)))
+ nkeep = len(keep)
+ # swap axis that should not be reduced to front
+ for i, s in enumerate(sorted(keep)):
+ a = a.swapaxes(i, s)
+ # merge reduced axis
+ a = a.reshape(a.shape[:nkeep] + (-1,))
+ kwargs['axis'] = -1
+ else:
+ keepdim = [1] * a.ndim
+
+ r = func(a, **kwargs)
+ return r, keepdim
+
+
+def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
"""
Compute the median along the specified axis.
@@ -2702,27 +2799,35 @@ def median(a, axis=None, out=None, overwrite_input=False):
----------
a : array_like
Input array or object that can be converted to an array.
- axis : int, optional
+ axis : int or sequence of int, optional
Axis along which the medians are computed. The default (axis=None)
is to compute the median along a flattened version of the array.
+ A sequence of axes is supported since version 1.9.0.
out : ndarray, optional
- Alternative output array in which to place the result. It must
- have the same shape and buffer length as the expected output,
- but the type (of the output) will be cast if necessary.
+ Alternative output array in which to place the result. It must have
+ the same shape and buffer length as the expected output, but the
+ type (of the output) will be cast if necessary.
overwrite_input : bool, optional
If True, then allow use of memory of input array (a) for
calculations. The input array will be modified by the call to
- median. This will save memory when you do not need to preserve
- the contents of the input array. Treat the input as undefined,
- but it will probably be fully or partially sorted. Default is
- False. Note that, if `overwrite_input` is True and the input
- is not already an ndarray, an error will be raised.
+ median. This will save memory when you do not need to preserve the
+ contents of the input array. Treat the input as undefined, but it
+ will probably be fully or partially sorted. Default is False. Note
+ that, if `overwrite_input` is True and the input is not already an
+ ndarray, an error will be raised.
+ keepdims : bool, optional
+ If this is set to True, the axes which are reduced are left
+ in the result as dimensions with size one. With this option,
+ the result will broadcast correctly against the original `arr`.
+
+ .. versionadded:: 1.9.0
+
Returns
-------
median : ndarray
- A new array holding the result (unless `out` is specified, in
- which case that array is returned instead). If the input contains
+ A new array holding the result (unless `out` is specified, in which
+ case that array is returned instead). If the input contains
integers, or floats of smaller precision than 64, then the output
data-type is float64. Otherwise, the output data-type is the same
as that of the input.
@@ -2766,6 +2871,16 @@ def median(a, axis=None, out=None, overwrite_input=False):
>>> assert not np.all(a==b)
"""
+ r, k = _ureduce(a, func=_median, axis=axis, out=out,
+ overwrite_input=overwrite_input)
+ if keepdims:
+ return r.reshape(k)
+ else:
+ return r
+
+def _median(a, axis=None, out=None, overwrite_input=False):
+ # can't be reasonably be implemented in terms of percentile as we have to
+ # call mean to not break astropy
a = np.asanyarray(a)
if axis is not None and axis >= a.ndim:
raise IndexError(
@@ -2815,7 +2930,7 @@ def median(a, axis=None, out=None, overwrite_input=False):
def percentile(a, q, axis=None, out=None,
- overwrite_input=False, interpolation='linear'):
+ overwrite_input=False, interpolation='linear', keepdims=False):
"""
Compute the qth percentile of the data along the specified axis.
@@ -2827,9 +2942,10 @@ def percentile(a, q, axis=None, out=None,
Input array or object that can be converted to an array.
q : float in range of [0,100] (or sequence of floats)
Percentile to compute which must be between 0 and 100 inclusive.
- axis : int, optional
+ axis : int or sequence of int, optional
Axis along which the percentiles are computed. The default (None)
is to compute the percentiles along a flattened version of the array.
+ A sequence of axes is supported since version 1.9.0.
out : ndarray, optional
Alternative output array in which to place the result. It must
have the same shape and buffer length as the expected output,
@@ -2855,17 +2971,23 @@ def percentile(a, q, axis=None, out=None,
* midpoint: (`i` + `j`) / 2.
.. versionadded:: 1.9.0
+ keepdims : bool, optional
+ If this is set to True, the axes which are reduced are left
+ in the result as dimensions with size one. With this option,
+ the result will broadcast correctly against the original `arr`.
+
+ .. versionadded:: 1.9.0
Returns
-------
percentile : scalar or ndarray
- If a single percentile `q` is given and axis=None a scalar is returned.
- If multiple percentiles `q` are given an array holding the result is
- returned. The results are listed in the first axis.
- (If `out` is specified, in which case that array is returned instead).
- If the input contains integers, or floats of smaller precision than 64,
- then the output data-type is float64. Otherwise, the output data-type
- is the same as that of the input.
+ If a single percentile `q` is given and axis=None a scalar is
+ returned. If multiple percentiles `q` are given an array holding
+ the result is returned. The results are listed in the first axis.
+ (If `out` is specified, in which case that array is returned
+ instead). If the input contains integers, or floats of smaller
+ precision than 64, then the output data-type is float64. Otherwise,
+ the output data-type is the same as that of the input.
See Also
--------
@@ -2873,12 +2995,12 @@ def percentile(a, q, axis=None, out=None,
Notes
-----
- Given a vector V of length N, the qth percentile of V is the qth ranked
- value in a sorted copy of V. The values and distances of the two nearest
- neighbors as well as the `interpolation` parameter will determine the
- percentile if the normalized ranking does not match q exactly. This
- function is the same as the median if ``q=50``, the same as the minimum
- if ``q=0``and the same as the maximum if ``q=100``.
+ Given a vector V of length N, the q-th percentile of V is the q-th ranked
+ value in a sorted copy of V. The values and distances of the two
+ nearest neighbors as well as the `interpolation` parameter will
+ determine the percentile if the normalized ranking does not match q
+ exactly. This function is the same as the median if ``q=50``, the same
+ as the minimum if ``q=0``and the same as the maximum if ``q=100``.
Examples
--------
@@ -2911,8 +3033,22 @@ def percentile(a, q, axis=None, out=None,
array([ 3.5])
"""
+ q = asarray(q, dtype=np.float64)
+ r, k = _ureduce(a, func=_percentile, q=q, axis=axis, out=out,
+ overwrite_input=overwrite_input,
+ interpolation=interpolation)
+ if keepdims:
+ if q.ndim == 0:
+ return r.reshape(k)
+ else:
+ return r.reshape([len(q)] + k)
+ else:
+ return r
+
+
+def _percentile(a, q, axis=None, out=None,
+ overwrite_input=False, interpolation='linear', keepdims=False):
a = asarray(a)
- q = asarray(q)
if q.ndim == 0:
# Do not allow 0-d arrays because following code fails for scalar
zerod = True
@@ -2920,10 +3056,17 @@ def percentile(a, q, axis=None, out=None,
else:
zerod = False
- q = q / 100.0
- if (q < 0).any() or (q > 1).any():
- raise ValueError(
- "Percentiles must be in the range [0,100]")
+ # avoid expensive reductions, relevant for arrays with < O(1000) elements
+ if q.size < 10:
+ for i in range(q.size):
+ if q[i] < 0. or q[i] > 100.:
+ raise ValueError("Percentiles must be in the range [0,100]")
+ q[i] /= 100.
+ else:
+ # faster than any()
+ if np.count_nonzero(q < 0.) or np.count_nonzero(q > 100.):
+ raise ValueError("Percentiles must be in the range [0,100]")
+ q /= 100.
# prepare a for partioning
if overwrite_input:
@@ -3029,10 +3172,11 @@ def trapz(y, x=None, dx=1.0, axis=-1):
Notes
-----
- Image [2]_ illustrates trapezoidal rule -- y-axis locations of points will
- be taken from `y` array, by default x-axis distances between points will be
- 1.0, alternatively they can be provided with `x` array or with `dx` scalar.
- Return value will be equal to combined area under the red lines.
+ Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
+ will be taken from `y` array, by default x-axis distances between
+ points will be 1.0, alternatively they can be provided with `x` array
+ or with `dx` scalar. Return value will be equal to combined area under
+ the red lines.
References
@@ -3130,7 +3274,7 @@ def meshgrid(*xi, **kwargs):
Make N-D coordinate arrays for vectorized evaluations of
N-D scalar/vector fields over N-D grids, given
one-dimensional coordinate arrays x1, x2,..., xn.
-
+
.. versionchanged:: 1.9
1-D and 0-D cases are allowed.
@@ -3141,16 +3285,22 @@ def meshgrid(*xi, **kwargs):
indexing : {'xy', 'ij'}, optional
Cartesian ('xy', default) or matrix ('ij') indexing of output.
See Notes for more details.
+
+ .. versionadded:: 1.7.0
sparse : bool, optional
- If True a sparse grid is returned in order to conserve memory.
- Default is False.
+ If True a sparse grid is returned in order to conserve memory.
+ Default is False.
+
+ .. versionadded:: 1.7.0
copy : bool, optional
- If False, a view into the original arrays are returned in
- order to conserve memory. Default is True. Please note that
- ``sparse=False, copy=False`` will likely return non-contiguous arrays.
- Furthermore, more than one element of a broadcast array may refer to
- a single memory location. If you need to write to the arrays, make
- copies first.
+ If False, a view into the original arrays are returned in order to
+ conserve memory. Default is True. Please note that
+ ``sparse=False, copy=False`` will likely return non-contiguous
+ arrays. Furthermore, more than one element of a broadcast array
+ may refer to a single memory location. If you need to write to the
+ arrays, make copies first.
+
+ .. versionadded:: 1.7.0
Returns
-------
@@ -3164,13 +3314,13 @@ def meshgrid(*xi, **kwargs):
Notes
-----
This function supports both indexing conventions through the indexing
- keyword argument. Giving the string 'ij' returns a meshgrid with matrix
- indexing, while 'xy' returns a meshgrid with Cartesian indexing. In the
- 2-D case with inputs of length M and N, the outputs are of shape (N, M) for
- 'xy' indexing and (M, N) for 'ij' indexing. In the 3-D case with inputs of
- length M, N and P, outputs are of shape (N, M, P) for 'xy' indexing and
- (M, N, P) for 'ij' indexing. The difference is illustrated by the
- following code snippet::
+ keyword argument. Giving the string 'ij' returns a meshgrid with
+ matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing.
+ In the 2-D case with inputs of length M and N, the outputs are of shape
+ (N, M) for 'xy' indexing and (M, N) for 'ij' indexing. In the 3-D case
+ with inputs of length M, N and P, outputs are of shape (N, M, P) for
+ 'xy' indexing and (M, N, P) for 'ij' indexing. The difference is
+ illustrated by the following code snippet::
xv, yv = meshgrid(x, y, sparse=False, indexing='ij')
for i in range(nx):
@@ -3181,7 +3331,7 @@ def meshgrid(*xi, **kwargs):
for i in range(nx):
for j in range(ny):
# treat xv[j,i], yv[j,i]
-
+
In the 1-D and 0-D case, the indexing and sparse keywords have no effect.
See Also
@@ -3221,9 +3371,13 @@ def meshgrid(*xi, **kwargs):
"""
ndim = len(xi)
- copy_ = kwargs.get('copy', True)
- sparse = kwargs.get('sparse', False)
- indexing = kwargs.get('indexing', 'xy')
+ copy_ = kwargs.pop('copy', True)
+ sparse = kwargs.pop('sparse', False)
+ indexing = kwargs.pop('indexing', 'xy')
+
+ if kwargs:
+ raise TypeError("meshgrid() got an unexpected keyword argument '%s'"
+ % (list(kwargs)[0],))
if not indexing in ['xy', 'ij']:
raise ValueError(
@@ -3258,7 +3412,8 @@ def meshgrid(*xi, **kwargs):
def delete(arr, obj, axis=None):
"""
Return a new array with sub-arrays along an axis deleted. For a one
- dimensional array, this returns those entries not returned by `arr[obj]`.
+ dimensional array, this returns those entries not returned by
+ `arr[obj]`.
Parameters
----------
@@ -3285,9 +3440,11 @@ def delete(arr, obj, axis=None):
Notes
-----
Often it is preferable to use a boolean mask. For example:
+
>>> mask = np.ones(len(arr), dtype=bool)
>>> mask[[0,2,4]] = False
>>> result = arr[mask,...]
+
Is equivalent to `np.delete(arr, [0,2,4], axis=0)`, but allows further
use of `mask`.
@@ -3465,7 +3622,8 @@ def insert(arr, obj, values, axis=None):
.. versionadded:: 1.8.0
Support for multiple insertions when `obj` is a single scalar or a
- sequence with one element (similar to calling insert multiple times).
+ sequence with one element (similar to calling insert multiple
+ times).
values : array_like
Values to insert into `arr`. If the type of `values` is different
from that of `arr`, `values` is converted to the type of `arr`.
@@ -3664,19 +3822,19 @@ def append(arr, values, axis=None):
Values are appended to a copy of this array.
values : array_like
These values are appended to a copy of `arr`. It must be of the
- correct shape (the same shape as `arr`, excluding `axis`). If `axis`
- is not specified, `values` can be any shape and will be flattened
- before use.
+ correct shape (the same shape as `arr`, excluding `axis`). If
+ `axis` is not specified, `values` can be any shape and will be
+ flattened before use.
axis : int, optional
- The axis along which `values` are appended. If `axis` is not given,
- both `arr` and `values` are flattened before use.
+ The axis along which `values` are appended. If `axis` is not
+ given, both `arr` and `values` are flattened before use.
Returns
-------
append : ndarray
- A copy of `arr` with `values` appended to `axis`. Note that `append`
- does not occur in-place: a new array is allocated and filled. If
- `axis` is None, `out` is a flattened array.
+ A copy of `arr` with `values` appended to `axis`. Note that
+ `append` does not occur in-place: a new array is allocated and
+ filled. If `axis` is None, `out` is a flattened array.
See Also
--------