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.py204
1 files changed, 143 insertions, 61 deletions
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 95edb95fa..75a39beaa 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -27,10 +27,11 @@ from numpy.core.fromnumeric import (
ravel, nonzero, sort, partition, mean, any, sum
)
from numpy.core.numerictypes import typecodes, number
+from numpy.core.function_base import add_newdoc
from numpy.lib.twodim_base import diag
from .utils import deprecate
from numpy.core.multiarray import (
- _insert, add_docstring, digitize, bincount, normalize_axis_index,
+ _insert, add_docstring, bincount, normalize_axis_index, _monotonicity,
interp as compiled_interp, interp_complex as compiled_interp_complex
)
from numpy.core.umath import _add_newdoc_ufunc as add_newdoc_ufunc
@@ -1308,7 +1309,7 @@ def interp(x, xp, fp, left=None, right=None, period=None):
return interp_func(x, xp, fp, left, right)
-def angle(z, deg=0):
+def angle(z, deg=False):
"""
Return the angle of the complex argument.
@@ -1324,6 +1325,9 @@ def angle(z, deg=0):
angle : ndarray or scalar
The counterclockwise angle from the positive real axis on
the complex plane, with dtype as numpy.float64.
+
+ ..versionchanged:: 1.16.0
+ This function works on subclasses of ndarray like `ma.array`.
See Also
--------
@@ -1338,18 +1342,18 @@ def angle(z, deg=0):
45.0
"""
- if deg:
- fact = 180/pi
- else:
- fact = 1.0
- z = asarray(z)
- if (issubclass(z.dtype.type, _nx.complexfloating)):
+ z = asanyarray(z)
+ if issubclass(z.dtype.type, _nx.complexfloating):
zimag = z.imag
zreal = z.real
else:
zimag = 0
zreal = z
- return arctan2(zimag, zreal) * fact
+
+ a = arctan2(zimag, zreal)
+ if deg:
+ a *= 180/pi
+ return a
def unwrap(p, discont=pi, axis=-1):
@@ -1649,7 +1653,7 @@ def disp(mesg, device=None, linefeed=True):
return
-# See http://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html
+# See https://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html
_DIMENSION_NAME = r'\w+'
_CORE_DIMENSION_LIST = '(?:{0:}(?:,{0:})*)?'.format(_DIMENSION_NAME)
_ARGUMENT = r'\({}\)'.format(_CORE_DIMENSION_LIST)
@@ -1906,7 +1910,7 @@ class vectorize(object):
References
----------
.. [1] NumPy Reference, section `Generalized Universal Function API
- <http://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html>`_.
+ <https://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html>`_.
"""
def __init__(self, pyfunc, otypes=None, doc=None, excluded=None,
@@ -2561,7 +2565,7 @@ def bartlett(M):
.. [3] A.V. Oppenheim and R.W. Schafer, "Discrete-Time Signal
Processing", Prentice-Hall, 1999, pp. 468-471.
.. [4] Wikipedia, "Window function",
- http://en.wikipedia.org/wiki/Window_function
+ https://en.wikipedia.org/wiki/Window_function
.. [5] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
"Numerical Recipes", Cambridge University Press, 1986, page 429.
@@ -2661,7 +2665,7 @@ def hanning(M):
.. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
The University of Alberta Press, 1975, pp. 106-108.
.. [3] Wikipedia, "Window function",
- http://en.wikipedia.org/wiki/Window_function
+ https://en.wikipedia.org/wiki/Window_function
.. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
"Numerical Recipes", Cambridge University Press, 1986, page 425.
@@ -2759,7 +2763,7 @@ def hamming(M):
.. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
University of Alberta Press, 1975, pp. 109-110.
.. [3] Wikipedia, "Window function",
- http://en.wikipedia.org/wiki/Window_function
+ https://en.wikipedia.org/wiki/Window_function
.. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
"Numerical Recipes", Cambridge University Press, 1986, page 425.
@@ -3036,7 +3040,7 @@ def kaiser(M, beta):
.. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
University of Alberta Press, 1975, pp. 177-178.
.. [3] Wikipedia, "Window function",
- http://en.wikipedia.org/wiki/Window_function
+ https://en.wikipedia.org/wiki/Window_function
Examples
--------
@@ -3124,7 +3128,7 @@ def sinc(x):
.. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
Resource. http://mathworld.wolfram.com/SincFunction.html
.. [2] Wikipedia, "Sinc function",
- http://en.wikipedia.org/wiki/Sinc_function
+ https://en.wikipedia.org/wiki/Sinc_function
Examples
--------
@@ -3398,9 +3402,9 @@ def _median(a, axis=None, out=None, overwrite_input=False):
def percentile(a, q, axis=None, out=None,
overwrite_input=False, interpolation='linear', keepdims=False):
"""
- Compute the qth percentile of the data along the specified axis.
+ Compute the q-th percentile of the data along the specified axis.
- Returns the qth percentile(s) of the array elements.
+ Returns the q-th percentile(s) of the array elements.
Parameters
----------
@@ -3467,7 +3471,7 @@ def percentile(a, q, axis=None, out=None,
Notes
-----
- Given a vector ``V`` of length ``N``, the ``q``-th percentile of
+ Given a vector ``V`` of length ``N``, the q-th percentile of
``V`` is the value ``q/100`` of the way from the minimum to the
maximum in a sorted copy of ``V``. The values and distances of
the two nearest neighbors as well as the `interpolation` parameter
@@ -3543,7 +3547,7 @@ def percentile(a, q, axis=None, out=None,
def quantile(a, q, axis=None, out=None,
overwrite_input=False, interpolation='linear', keepdims=False):
"""
- Compute the `q`th quantile of the data along the specified axis.
+ Compute the q-th quantile of the data along the specified axis.
..versionadded:: 1.15.0
Parameters
@@ -3569,6 +3573,7 @@ def quantile(a, q, axis=None, out=None,
This optional parameter specifies the interpolation method to
use when the desired quantile lies between two data points
``i < j``:
+
* linear: ``i + (j - i) * fraction``, where ``fraction``
is the fractional part of the index surrounded by ``i``
and ``j``.
@@ -3602,7 +3607,7 @@ def quantile(a, q, axis=None, out=None,
Notes
-----
- Given a vector ``V`` of length ``N``, the ``q``-th quantile of
+ Given a vector ``V`` of length ``N``, the q-th quantile of
``V`` is the value ``q`` of the way from the minimum to the
maximum in a sorted copy of ``V``. The values and distances of
the two nearest neighbors as well as the `interpolation` parameter
@@ -3720,7 +3725,7 @@ def _quantile_ureduce_func(a, q, axis=None, out=None, overwrite_input=False,
indices = concatenate((indices, [-1]))
ap.partition(indices, axis=axis)
- # ensure axis with qth is first
+ # ensure axis with q-th is first
ap = np.moveaxis(ap, axis, 0)
axis = 0
@@ -3753,7 +3758,7 @@ def _quantile_ureduce_func(a, q, axis=None, out=None, overwrite_input=False,
ap.partition(concatenate((indices_below, indices_above)), axis=axis)
- # ensure axis with qth is first
+ # ensure axis with q-th is first
ap = np.moveaxis(ap, axis, 0)
weights_below = np.moveaxis(weights_below, axis, 0)
weights_above = np.moveaxis(weights_above, axis, 0)
@@ -3767,7 +3772,7 @@ def _quantile_ureduce_func(a, q, axis=None, out=None, overwrite_input=False,
x1 = take(ap, indices_below, axis=axis) * weights_below
x2 = take(ap, indices_above, axis=axis) * weights_above
- # ensure axis with qth is first
+ # ensure axis with q-th is first
x1 = np.moveaxis(x1, axis, 0)
x2 = np.moveaxis(x2, axis, 0)
@@ -3840,10 +3845,10 @@ def trapz(y, x=None, dx=1.0, axis=-1):
References
----------
- .. [1] Wikipedia page: http://en.wikipedia.org/wiki/Trapezoidal_rule
+ .. [1] Wikipedia page: https://en.wikipedia.org/wiki/Trapezoidal_rule
.. [2] Illustration image:
- http://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png
+ https://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png
Examples
--------
@@ -3891,41 +3896,6 @@ def trapz(y, x=None, dx=1.0, axis=-1):
return ret
-#always succeed
-def add_newdoc(place, obj, doc):
- """
- Adds documentation to obj which is in module place.
-
- If doc is a string add it to obj as a docstring
-
- If doc is a tuple, then the first element is interpreted as
- an attribute of obj and the second as the docstring
- (method, docstring)
-
- If doc is a list, then each element of the list should be a
- sequence of length two --> [(method1, docstring1),
- (method2, docstring2), ...]
-
- This routine never raises an error.
-
- This routine cannot modify read-only docstrings, as appear
- in new-style classes or built-in functions. Because this
- routine never raises an error the caller must check manually
- that the docstrings were changed.
- """
- try:
- new = getattr(__import__(place, globals(), {}, [obj]), obj)
- if isinstance(doc, str):
- add_docstring(new, doc.strip())
- elif isinstance(doc, tuple):
- add_docstring(getattr(new, doc[0]), doc[1].strip())
- elif isinstance(doc, list):
- for val in doc:
- add_docstring(getattr(new, val[0]), val[1].strip())
- except Exception:
- pass
-
-
# Based on scitools meshgrid
def meshgrid(*xi, **kwargs):
"""
@@ -4022,11 +3992,13 @@ def meshgrid(*xi, **kwargs):
`meshgrid` is very useful to evaluate functions on a grid.
+ >>> import matplotlib.pyplot as plt
>>> x = np.arange(-5, 5, 0.1)
>>> y = np.arange(-5, 5, 0.1)
>>> xx, yy = np.meshgrid(x, y, sparse=True)
>>> z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
>>> h = plt.contourf(x,y,z)
+ >>> plt.show()
"""
ndim = len(xi)
@@ -4526,3 +4498,113 @@ def append(arr, values, axis=None):
values = ravel(values)
axis = arr.ndim-1
return concatenate((arr, values), axis=axis)
+
+
+def digitize(x, bins, right=False):
+ """
+ Return the indices of the bins to which each value in input array belongs.
+
+ ========= ============= ============================
+ `right` order of bins returned index `i` satisfies
+ ========= ============= ============================
+ ``False`` increasing ``bins[i-1] <= x < bins[i]``
+ ``True`` increasing ``bins[i-1] < x <= bins[i]``
+ ``False`` decreasing ``bins[i-1] > x >= bins[i]``
+ ``True`` decreasing ``bins[i-1] >= x > bins[i]``
+ ========= ============= ============================
+
+ If values in `x` are beyond the bounds of `bins`, 0 or ``len(bins)`` is
+ returned as appropriate.
+
+ Parameters
+ ----------
+ x : array_like
+ Input array to be binned. Prior to NumPy 1.10.0, this array had to
+ be 1-dimensional, but can now have any shape.
+ bins : array_like
+ Array of bins. It has to be 1-dimensional and monotonic.
+ right : bool, optional
+ Indicating whether the intervals include the right or the left bin
+ edge. Default behavior is (right==False) indicating that the interval
+ does not include the right edge. The left bin end is open in this
+ case, i.e., bins[i-1] <= x < bins[i] is the default behavior for
+ monotonically increasing bins.
+
+ Returns
+ -------
+ indices : ndarray of ints
+ Output array of indices, of same shape as `x`.
+
+ Raises
+ ------
+ ValueError
+ If `bins` is not monotonic.
+ TypeError
+ If the type of the input is complex.
+
+ See Also
+ --------
+ bincount, histogram, unique, searchsorted
+
+ Notes
+ -----
+ If values in `x` are such that they fall outside the bin range,
+ attempting to index `bins` with the indices that `digitize` returns
+ will result in an IndexError.
+
+ .. versionadded:: 1.10.0
+
+ `np.digitize` is implemented in terms of `np.searchsorted`. This means
+ that a binary search is used to bin the values, which scales much better
+ for larger number of bins than the previous linear search. It also removes
+ the requirement for the input array to be 1-dimensional.
+
+ For monotonically _increasing_ `bins`, the following are equivalent::
+
+ np.digitize(x, bins, right=True)
+ np.searchsorted(bins, x, side='left')
+
+ Note that as the order of the arguments are reversed, the side must be too.
+ The `searchsorted` call is marginally faster, as it does not do any
+ monotonicity checks. Perhaps more importantly, it supports all dtypes.
+
+ Examples
+ --------
+ >>> x = np.array([0.2, 6.4, 3.0, 1.6])
+ >>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
+ >>> inds = np.digitize(x, bins)
+ >>> inds
+ array([1, 4, 3, 2])
+ >>> for n in range(x.size):
+ ... print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]])
+ ...
+ 0.0 <= 0.2 < 1.0
+ 4.0 <= 6.4 < 10.0
+ 2.5 <= 3.0 < 4.0
+ 1.0 <= 1.6 < 2.5
+
+ >>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.])
+ >>> bins = np.array([0, 5, 10, 15, 20])
+ >>> np.digitize(x,bins,right=True)
+ array([1, 2, 3, 4, 4])
+ >>> np.digitize(x,bins,right=False)
+ array([1, 3, 3, 4, 5])
+ """
+ x = _nx.asarray(x)
+ bins = _nx.asarray(bins)
+
+ # here for compatibility, searchsorted below is happy to take this
+ if np.issubdtype(x.dtype, _nx.complexfloating):
+ raise TypeError("x may not be complex")
+
+ mono = _monotonicity(bins)
+ if mono == 0:
+ raise ValueError("bins must be monotonically increasing or decreasing")
+
+ # this is backwards because the arguments below are swapped
+ side = 'left' if right else 'right'
+ if mono == -1:
+ # reverse the bins, and invert the results
+ return len(bins) - _nx.searchsorted(bins[::-1], x, side=side)
+ else:
+ return _nx.searchsorted(bins, x, side=side)