annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/lib/function_base.py @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2a2c65a20a8b
children
rev   line source
Chris@87 1 from __future__ import division, absolute_import, print_function
Chris@87 2
Chris@87 3 import warnings
Chris@87 4 import sys
Chris@87 5 import collections
Chris@87 6 import operator
Chris@87 7
Chris@87 8 import numpy as np
Chris@87 9 import numpy.core.numeric as _nx
Chris@87 10 from numpy.core import linspace, atleast_1d, atleast_2d
Chris@87 11 from numpy.core.numeric import (
Chris@87 12 ones, zeros, arange, concatenate, array, asarray, asanyarray, empty,
Chris@87 13 empty_like, ndarray, around, floor, ceil, take, dot, where, intp,
Chris@87 14 integer, isscalar
Chris@87 15 )
Chris@87 16 from numpy.core.umath import (
Chris@87 17 pi, multiply, add, arctan2, frompyfunc, cos, less_equal, sqrt, sin,
Chris@87 18 mod, exp, log10
Chris@87 19 )
Chris@87 20 from numpy.core.fromnumeric import (
Chris@87 21 ravel, nonzero, sort, partition, mean
Chris@87 22 )
Chris@87 23 from numpy.core.numerictypes import typecodes, number
Chris@87 24 from numpy.lib.twodim_base import diag
Chris@87 25 from .utils import deprecate
Chris@87 26 from ._compiled_base import _insert, add_docstring
Chris@87 27 from ._compiled_base import digitize, bincount, interp as compiled_interp
Chris@87 28 from ._compiled_base import add_newdoc_ufunc
Chris@87 29 from numpy.compat import long
Chris@87 30
Chris@87 31 # Force range to be a generator, for np.delete's usage.
Chris@87 32 if sys.version_info[0] < 3:
Chris@87 33 range = xrange
Chris@87 34
Chris@87 35
Chris@87 36 __all__ = [
Chris@87 37 'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile',
Chris@87 38 'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp',
Chris@87 39 'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average',
Chris@87 40 'histogram', 'histogramdd', 'bincount', 'digitize', 'cov', 'corrcoef',
Chris@87 41 'msort', 'median', 'sinc', 'hamming', 'hanning', 'bartlett',
Chris@87 42 'blackman', 'kaiser', 'trapz', 'i0', 'add_newdoc', 'add_docstring',
Chris@87 43 'meshgrid', 'delete', 'insert', 'append', 'interp', 'add_newdoc_ufunc'
Chris@87 44 ]
Chris@87 45
Chris@87 46
Chris@87 47 def iterable(y):
Chris@87 48 """
Chris@87 49 Check whether or not an object can be iterated over.
Chris@87 50
Chris@87 51 Parameters
Chris@87 52 ----------
Chris@87 53 y : object
Chris@87 54 Input object.
Chris@87 55
Chris@87 56 Returns
Chris@87 57 -------
Chris@87 58 b : {0, 1}
Chris@87 59 Return 1 if the object has an iterator method or is a sequence,
Chris@87 60 and 0 otherwise.
Chris@87 61
Chris@87 62
Chris@87 63 Examples
Chris@87 64 --------
Chris@87 65 >>> np.iterable([1, 2, 3])
Chris@87 66 1
Chris@87 67 >>> np.iterable(2)
Chris@87 68 0
Chris@87 69
Chris@87 70 """
Chris@87 71 try:
Chris@87 72 iter(y)
Chris@87 73 except:
Chris@87 74 return 0
Chris@87 75 return 1
Chris@87 76
Chris@87 77
Chris@87 78 def histogram(a, bins=10, range=None, normed=False, weights=None,
Chris@87 79 density=None):
Chris@87 80 """
Chris@87 81 Compute the histogram of a set of data.
Chris@87 82
Chris@87 83 Parameters
Chris@87 84 ----------
Chris@87 85 a : array_like
Chris@87 86 Input data. The histogram is computed over the flattened array.
Chris@87 87 bins : int or sequence of scalars, optional
Chris@87 88 If `bins` is an int, it defines the number of equal-width
Chris@87 89 bins in the given range (10, by default). If `bins` is a sequence,
Chris@87 90 it defines the bin edges, including the rightmost edge, allowing
Chris@87 91 for non-uniform bin widths.
Chris@87 92 range : (float, float), optional
Chris@87 93 The lower and upper range of the bins. If not provided, range
Chris@87 94 is simply ``(a.min(), a.max())``. Values outside the range are
Chris@87 95 ignored.
Chris@87 96 normed : bool, optional
Chris@87 97 This keyword is deprecated in Numpy 1.6 due to confusing/buggy
Chris@87 98 behavior. It will be removed in Numpy 2.0. Use the density keyword
Chris@87 99 instead.
Chris@87 100 If False, the result will contain the number of samples
Chris@87 101 in each bin. If True, the result is the value of the
Chris@87 102 probability *density* function at the bin, normalized such that
Chris@87 103 the *integral* over the range is 1. Note that this latter behavior is
Chris@87 104 known to be buggy with unequal bin widths; use `density` instead.
Chris@87 105 weights : array_like, optional
Chris@87 106 An array of weights, of the same shape as `a`. Each value in `a`
Chris@87 107 only contributes its associated weight towards the bin count
Chris@87 108 (instead of 1). If `normed` is True, the weights are normalized,
Chris@87 109 so that the integral of the density over the range remains 1
Chris@87 110 density : bool, optional
Chris@87 111 If False, the result will contain the number of samples
Chris@87 112 in each bin. If True, the result is the value of the
Chris@87 113 probability *density* function at the bin, normalized such that
Chris@87 114 the *integral* over the range is 1. Note that the sum of the
Chris@87 115 histogram values will not be equal to 1 unless bins of unity
Chris@87 116 width are chosen; it is not a probability *mass* function.
Chris@87 117 Overrides the `normed` keyword if given.
Chris@87 118
Chris@87 119 Returns
Chris@87 120 -------
Chris@87 121 hist : array
Chris@87 122 The values of the histogram. See `normed` and `weights` for a
Chris@87 123 description of the possible semantics.
Chris@87 124 bin_edges : array of dtype float
Chris@87 125 Return the bin edges ``(length(hist)+1)``.
Chris@87 126
Chris@87 127
Chris@87 128 See Also
Chris@87 129 --------
Chris@87 130 histogramdd, bincount, searchsorted, digitize
Chris@87 131
Chris@87 132 Notes
Chris@87 133 -----
Chris@87 134 All but the last (righthand-most) bin is half-open. In other words, if
Chris@87 135 `bins` is::
Chris@87 136
Chris@87 137 [1, 2, 3, 4]
Chris@87 138
Chris@87 139 then the first bin is ``[1, 2)`` (including 1, but excluding 2) and the
Chris@87 140 second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which *includes*
Chris@87 141 4.
Chris@87 142
Chris@87 143 Examples
Chris@87 144 --------
Chris@87 145 >>> np.histogram([1, 2, 1], bins=[0, 1, 2, 3])
Chris@87 146 (array([0, 2, 1]), array([0, 1, 2, 3]))
Chris@87 147 >>> np.histogram(np.arange(4), bins=np.arange(5), density=True)
Chris@87 148 (array([ 0.25, 0.25, 0.25, 0.25]), array([0, 1, 2, 3, 4]))
Chris@87 149 >>> np.histogram([[1, 2, 1], [1, 0, 1]], bins=[0,1,2,3])
Chris@87 150 (array([1, 4, 1]), array([0, 1, 2, 3]))
Chris@87 151
Chris@87 152 >>> a = np.arange(5)
Chris@87 153 >>> hist, bin_edges = np.histogram(a, density=True)
Chris@87 154 >>> hist
Chris@87 155 array([ 0.5, 0. , 0.5, 0. , 0. , 0.5, 0. , 0.5, 0. , 0.5])
Chris@87 156 >>> hist.sum()
Chris@87 157 2.4999999999999996
Chris@87 158 >>> np.sum(hist*np.diff(bin_edges))
Chris@87 159 1.0
Chris@87 160
Chris@87 161 """
Chris@87 162
Chris@87 163 a = asarray(a)
Chris@87 164 if weights is not None:
Chris@87 165 weights = asarray(weights)
Chris@87 166 if np.any(weights.shape != a.shape):
Chris@87 167 raise ValueError(
Chris@87 168 'weights should have the same shape as a.')
Chris@87 169 weights = weights.ravel()
Chris@87 170 a = a.ravel()
Chris@87 171
Chris@87 172 if (range is not None):
Chris@87 173 mn, mx = range
Chris@87 174 if (mn > mx):
Chris@87 175 raise AttributeError(
Chris@87 176 'max must be larger than min in range parameter.')
Chris@87 177
Chris@87 178 if not iterable(bins):
Chris@87 179 if np.isscalar(bins) and bins < 1:
Chris@87 180 raise ValueError(
Chris@87 181 '`bins` should be a positive integer.')
Chris@87 182 if range is None:
Chris@87 183 if a.size == 0:
Chris@87 184 # handle empty arrays. Can't determine range, so use 0-1.
Chris@87 185 range = (0, 1)
Chris@87 186 else:
Chris@87 187 range = (a.min(), a.max())
Chris@87 188 mn, mx = [mi + 0.0 for mi in range]
Chris@87 189 if mn == mx:
Chris@87 190 mn -= 0.5
Chris@87 191 mx += 0.5
Chris@87 192 bins = linspace(mn, mx, bins + 1, endpoint=True)
Chris@87 193 else:
Chris@87 194 bins = asarray(bins)
Chris@87 195 if (np.diff(bins) < 0).any():
Chris@87 196 raise AttributeError(
Chris@87 197 'bins must increase monotonically.')
Chris@87 198
Chris@87 199 # Histogram is an integer or a float array depending on the weights.
Chris@87 200 if weights is None:
Chris@87 201 ntype = int
Chris@87 202 else:
Chris@87 203 ntype = weights.dtype
Chris@87 204 n = np.zeros(bins.shape, ntype)
Chris@87 205
Chris@87 206 block = 65536
Chris@87 207 if weights is None:
Chris@87 208 for i in arange(0, len(a), block):
Chris@87 209 sa = sort(a[i:i+block])
Chris@87 210 n += np.r_[sa.searchsorted(bins[:-1], 'left'),
Chris@87 211 sa.searchsorted(bins[-1], 'right')]
Chris@87 212 else:
Chris@87 213 zero = array(0, dtype=ntype)
Chris@87 214 for i in arange(0, len(a), block):
Chris@87 215 tmp_a = a[i:i+block]
Chris@87 216 tmp_w = weights[i:i+block]
Chris@87 217 sorting_index = np.argsort(tmp_a)
Chris@87 218 sa = tmp_a[sorting_index]
Chris@87 219 sw = tmp_w[sorting_index]
Chris@87 220 cw = np.concatenate(([zero, ], sw.cumsum()))
Chris@87 221 bin_index = np.r_[sa.searchsorted(bins[:-1], 'left'),
Chris@87 222 sa.searchsorted(bins[-1], 'right')]
Chris@87 223 n += cw[bin_index]
Chris@87 224
Chris@87 225 n = np.diff(n)
Chris@87 226
Chris@87 227 if density is not None:
Chris@87 228 if density:
Chris@87 229 db = array(np.diff(bins), float)
Chris@87 230 return n/db/n.sum(), bins
Chris@87 231 else:
Chris@87 232 return n, bins
Chris@87 233 else:
Chris@87 234 # deprecated, buggy behavior. Remove for Numpy 2.0
Chris@87 235 if normed:
Chris@87 236 db = array(np.diff(bins), float)
Chris@87 237 return n/(n*db).sum(), bins
Chris@87 238 else:
Chris@87 239 return n, bins
Chris@87 240
Chris@87 241
Chris@87 242 def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
Chris@87 243 """
Chris@87 244 Compute the multidimensional histogram of some data.
Chris@87 245
Chris@87 246 Parameters
Chris@87 247 ----------
Chris@87 248 sample : array_like
Chris@87 249 The data to be histogrammed. It must be an (N,D) array or data
Chris@87 250 that can be converted to such. The rows of the resulting array
Chris@87 251 are the coordinates of points in a D dimensional polytope.
Chris@87 252 bins : sequence or int, optional
Chris@87 253 The bin specification:
Chris@87 254
Chris@87 255 * A sequence of arrays describing the bin edges along each dimension.
Chris@87 256 * The number of bins for each dimension (nx, ny, ... =bins)
Chris@87 257 * The number of bins for all dimensions (nx=ny=...=bins).
Chris@87 258
Chris@87 259 range : sequence, optional
Chris@87 260 A sequence of lower and upper bin edges to be used if the edges are
Chris@87 261 not given explicitly in `bins`. Defaults to the minimum and maximum
Chris@87 262 values along each dimension.
Chris@87 263 normed : bool, optional
Chris@87 264 If False, returns the number of samples in each bin. If True,
Chris@87 265 returns the bin density ``bin_count / sample_count / bin_volume``.
Chris@87 266 weights : array_like (N,), optional
Chris@87 267 An array of values `w_i` weighing each sample `(x_i, y_i, z_i, ...)`.
Chris@87 268 Weights are normalized to 1 if normed is True. If normed is False,
Chris@87 269 the values of the returned histogram are equal to the sum of the
Chris@87 270 weights belonging to the samples falling into each bin.
Chris@87 271
Chris@87 272 Returns
Chris@87 273 -------
Chris@87 274 H : ndarray
Chris@87 275 The multidimensional histogram of sample x. See normed and weights
Chris@87 276 for the different possible semantics.
Chris@87 277 edges : list
Chris@87 278 A list of D arrays describing the bin edges for each dimension.
Chris@87 279
Chris@87 280 See Also
Chris@87 281 --------
Chris@87 282 histogram: 1-D histogram
Chris@87 283 histogram2d: 2-D histogram
Chris@87 284
Chris@87 285 Examples
Chris@87 286 --------
Chris@87 287 >>> r = np.random.randn(100,3)
Chris@87 288 >>> H, edges = np.histogramdd(r, bins = (5, 8, 4))
Chris@87 289 >>> H.shape, edges[0].size, edges[1].size, edges[2].size
Chris@87 290 ((5, 8, 4), 6, 9, 5)
Chris@87 291
Chris@87 292 """
Chris@87 293
Chris@87 294 try:
Chris@87 295 # Sample is an ND-array.
Chris@87 296 N, D = sample.shape
Chris@87 297 except (AttributeError, ValueError):
Chris@87 298 # Sample is a sequence of 1D arrays.
Chris@87 299 sample = atleast_2d(sample).T
Chris@87 300 N, D = sample.shape
Chris@87 301
Chris@87 302 nbin = empty(D, int)
Chris@87 303 edges = D*[None]
Chris@87 304 dedges = D*[None]
Chris@87 305 if weights is not None:
Chris@87 306 weights = asarray(weights)
Chris@87 307
Chris@87 308 try:
Chris@87 309 M = len(bins)
Chris@87 310 if M != D:
Chris@87 311 raise AttributeError(
Chris@87 312 'The dimension of bins must be equal to the dimension of the '
Chris@87 313 ' sample x.')
Chris@87 314 except TypeError:
Chris@87 315 # bins is an integer
Chris@87 316 bins = D*[bins]
Chris@87 317
Chris@87 318 # Select range for each dimension
Chris@87 319 # Used only if number of bins is given.
Chris@87 320 if range is None:
Chris@87 321 # Handle empty input. Range can't be determined in that case, use 0-1.
Chris@87 322 if N == 0:
Chris@87 323 smin = zeros(D)
Chris@87 324 smax = ones(D)
Chris@87 325 else:
Chris@87 326 smin = atleast_1d(array(sample.min(0), float))
Chris@87 327 smax = atleast_1d(array(sample.max(0), float))
Chris@87 328 else:
Chris@87 329 smin = zeros(D)
Chris@87 330 smax = zeros(D)
Chris@87 331 for i in arange(D):
Chris@87 332 smin[i], smax[i] = range[i]
Chris@87 333
Chris@87 334 # Make sure the bins have a finite width.
Chris@87 335 for i in arange(len(smin)):
Chris@87 336 if smin[i] == smax[i]:
Chris@87 337 smin[i] = smin[i] - .5
Chris@87 338 smax[i] = smax[i] + .5
Chris@87 339
Chris@87 340 # avoid rounding issues for comparisons when dealing with inexact types
Chris@87 341 if np.issubdtype(sample.dtype, np.inexact):
Chris@87 342 edge_dt = sample.dtype
Chris@87 343 else:
Chris@87 344 edge_dt = float
Chris@87 345 # Create edge arrays
Chris@87 346 for i in arange(D):
Chris@87 347 if isscalar(bins[i]):
Chris@87 348 if bins[i] < 1:
Chris@87 349 raise ValueError(
Chris@87 350 "Element at index %s in `bins` should be a positive "
Chris@87 351 "integer." % i)
Chris@87 352 nbin[i] = bins[i] + 2 # +2 for outlier bins
Chris@87 353 edges[i] = linspace(smin[i], smax[i], nbin[i]-1, dtype=edge_dt)
Chris@87 354 else:
Chris@87 355 edges[i] = asarray(bins[i], edge_dt)
Chris@87 356 nbin[i] = len(edges[i]) + 1 # +1 for outlier bins
Chris@87 357 dedges[i] = diff(edges[i])
Chris@87 358 if np.any(np.asarray(dedges[i]) <= 0):
Chris@87 359 raise ValueError(
Chris@87 360 "Found bin edge of size <= 0. Did you specify `bins` with"
Chris@87 361 "non-monotonic sequence?")
Chris@87 362
Chris@87 363 nbin = asarray(nbin)
Chris@87 364
Chris@87 365 # Handle empty input.
Chris@87 366 if N == 0:
Chris@87 367 return np.zeros(nbin-2), edges
Chris@87 368
Chris@87 369 # Compute the bin number each sample falls into.
Chris@87 370 Ncount = {}
Chris@87 371 for i in arange(D):
Chris@87 372 Ncount[i] = digitize(sample[:, i], edges[i])
Chris@87 373
Chris@87 374 # Using digitize, values that fall on an edge are put in the right bin.
Chris@87 375 # For the rightmost bin, we want values equal to the right edge to be
Chris@87 376 # counted in the last bin, and not as an outlier.
Chris@87 377 for i in arange(D):
Chris@87 378 # Rounding precision
Chris@87 379 mindiff = dedges[i].min()
Chris@87 380 if not np.isinf(mindiff):
Chris@87 381 decimal = int(-log10(mindiff)) + 6
Chris@87 382 # Find which points are on the rightmost edge.
Chris@87 383 not_smaller_than_edge = (sample[:, i] >= edges[i][-1])
Chris@87 384 on_edge = (around(sample[:, i], decimal) ==
Chris@87 385 around(edges[i][-1], decimal))
Chris@87 386 # Shift these points one bin to the left.
Chris@87 387 Ncount[i][where(on_edge & not_smaller_than_edge)[0]] -= 1
Chris@87 388
Chris@87 389 # Flattened histogram matrix (1D)
Chris@87 390 # Reshape is used so that overlarge arrays
Chris@87 391 # will raise an error.
Chris@87 392 hist = zeros(nbin, float).reshape(-1)
Chris@87 393
Chris@87 394 # Compute the sample indices in the flattened histogram matrix.
Chris@87 395 ni = nbin.argsort()
Chris@87 396 xy = zeros(N, int)
Chris@87 397 for i in arange(0, D-1):
Chris@87 398 xy += Ncount[ni[i]] * nbin[ni[i+1:]].prod()
Chris@87 399 xy += Ncount[ni[-1]]
Chris@87 400
Chris@87 401 # Compute the number of repetitions in xy and assign it to the
Chris@87 402 # flattened histmat.
Chris@87 403 if len(xy) == 0:
Chris@87 404 return zeros(nbin-2, int), edges
Chris@87 405
Chris@87 406 flatcount = bincount(xy, weights)
Chris@87 407 a = arange(len(flatcount))
Chris@87 408 hist[a] = flatcount
Chris@87 409
Chris@87 410 # Shape into a proper matrix
Chris@87 411 hist = hist.reshape(sort(nbin))
Chris@87 412 for i in arange(nbin.size):
Chris@87 413 j = ni.argsort()[i]
Chris@87 414 hist = hist.swapaxes(i, j)
Chris@87 415 ni[i], ni[j] = ni[j], ni[i]
Chris@87 416
Chris@87 417 # Remove outliers (indices 0 and -1 for each dimension).
Chris@87 418 core = D*[slice(1, -1)]
Chris@87 419 hist = hist[core]
Chris@87 420
Chris@87 421 # Normalize if normed is True
Chris@87 422 if normed:
Chris@87 423 s = hist.sum()
Chris@87 424 for i in arange(D):
Chris@87 425 shape = ones(D, int)
Chris@87 426 shape[i] = nbin[i] - 2
Chris@87 427 hist = hist / dedges[i].reshape(shape)
Chris@87 428 hist /= s
Chris@87 429
Chris@87 430 if (hist.shape != nbin - 2).any():
Chris@87 431 raise RuntimeError(
Chris@87 432 "Internal Shape Error")
Chris@87 433 return hist, edges
Chris@87 434
Chris@87 435
Chris@87 436 def average(a, axis=None, weights=None, returned=False):
Chris@87 437 """
Chris@87 438 Compute the weighted average along the specified axis.
Chris@87 439
Chris@87 440 Parameters
Chris@87 441 ----------
Chris@87 442 a : array_like
Chris@87 443 Array containing data to be averaged. If `a` is not an array, a
Chris@87 444 conversion is attempted.
Chris@87 445 axis : int, optional
Chris@87 446 Axis along which to average `a`. If `None`, averaging is done over
Chris@87 447 the flattened array.
Chris@87 448 weights : array_like, optional
Chris@87 449 An array of weights associated with the values in `a`. Each value in
Chris@87 450 `a` contributes to the average according to its associated weight.
Chris@87 451 The weights array can either be 1-D (in which case its length must be
Chris@87 452 the size of `a` along the given axis) or of the same shape as `a`.
Chris@87 453 If `weights=None`, then all data in `a` are assumed to have a
Chris@87 454 weight equal to one.
Chris@87 455 returned : bool, optional
Chris@87 456 Default is `False`. If `True`, the tuple (`average`, `sum_of_weights`)
Chris@87 457 is returned, otherwise only the average is returned.
Chris@87 458 If `weights=None`, `sum_of_weights` is equivalent to the number of
Chris@87 459 elements over which the average is taken.
Chris@87 460
Chris@87 461
Chris@87 462 Returns
Chris@87 463 -------
Chris@87 464 average, [sum_of_weights] : {array_type, double}
Chris@87 465 Return the average along the specified axis. When returned is `True`,
Chris@87 466 return a tuple with the average as the first element and the sum
Chris@87 467 of the weights as the second element. The return type is `Float`
Chris@87 468 if `a` is of integer type, otherwise it is of the same type as `a`.
Chris@87 469 `sum_of_weights` is of the same type as `average`.
Chris@87 470
Chris@87 471 Raises
Chris@87 472 ------
Chris@87 473 ZeroDivisionError
Chris@87 474 When all weights along axis are zero. See `numpy.ma.average` for a
Chris@87 475 version robust to this type of error.
Chris@87 476 TypeError
Chris@87 477 When the length of 1D `weights` is not the same as the shape of `a`
Chris@87 478 along axis.
Chris@87 479
Chris@87 480 See Also
Chris@87 481 --------
Chris@87 482 mean
Chris@87 483
Chris@87 484 ma.average : average for masked arrays -- useful if your data contains
Chris@87 485 "missing" values
Chris@87 486
Chris@87 487 Examples
Chris@87 488 --------
Chris@87 489 >>> data = range(1,5)
Chris@87 490 >>> data
Chris@87 491 [1, 2, 3, 4]
Chris@87 492 >>> np.average(data)
Chris@87 493 2.5
Chris@87 494 >>> np.average(range(1,11), weights=range(10,0,-1))
Chris@87 495 4.0
Chris@87 496
Chris@87 497 >>> data = np.arange(6).reshape((3,2))
Chris@87 498 >>> data
Chris@87 499 array([[0, 1],
Chris@87 500 [2, 3],
Chris@87 501 [4, 5]])
Chris@87 502 >>> np.average(data, axis=1, weights=[1./4, 3./4])
Chris@87 503 array([ 0.75, 2.75, 4.75])
Chris@87 504 >>> np.average(data, weights=[1./4, 3./4])
Chris@87 505 Traceback (most recent call last):
Chris@87 506 ...
Chris@87 507 TypeError: Axis must be specified when shapes of a and weights differ.
Chris@87 508
Chris@87 509 """
Chris@87 510 if not isinstance(a, np.matrix):
Chris@87 511 a = np.asarray(a)
Chris@87 512
Chris@87 513 if weights is None:
Chris@87 514 avg = a.mean(axis)
Chris@87 515 scl = avg.dtype.type(a.size/avg.size)
Chris@87 516 else:
Chris@87 517 a = a + 0.0
Chris@87 518 wgt = np.array(weights, dtype=a.dtype, copy=0)
Chris@87 519
Chris@87 520 # Sanity checks
Chris@87 521 if a.shape != wgt.shape:
Chris@87 522 if axis is None:
Chris@87 523 raise TypeError(
Chris@87 524 "Axis must be specified when shapes of a and weights "
Chris@87 525 "differ.")
Chris@87 526 if wgt.ndim != 1:
Chris@87 527 raise TypeError(
Chris@87 528 "1D weights expected when shapes of a and weights differ.")
Chris@87 529 if wgt.shape[0] != a.shape[axis]:
Chris@87 530 raise ValueError(
Chris@87 531 "Length of weights not compatible with specified axis.")
Chris@87 532
Chris@87 533 # setup wgt to broadcast along axis
Chris@87 534 wgt = np.array(wgt, copy=0, ndmin=a.ndim).swapaxes(-1, axis)
Chris@87 535
Chris@87 536 scl = wgt.sum(axis=axis)
Chris@87 537 if (scl == 0.0).any():
Chris@87 538 raise ZeroDivisionError(
Chris@87 539 "Weights sum to zero, can't be normalized")
Chris@87 540
Chris@87 541 avg = np.multiply(a, wgt).sum(axis)/scl
Chris@87 542
Chris@87 543 if returned:
Chris@87 544 scl = np.multiply(avg, 0) + scl
Chris@87 545 return avg, scl
Chris@87 546 else:
Chris@87 547 return avg
Chris@87 548
Chris@87 549
Chris@87 550 def asarray_chkfinite(a, dtype=None, order=None):
Chris@87 551 """
Chris@87 552 Convert the input to an array, checking for NaNs or Infs.
Chris@87 553
Chris@87 554 Parameters
Chris@87 555 ----------
Chris@87 556 a : array_like
Chris@87 557 Input data, in any form that can be converted to an array. This
Chris@87 558 includes lists, lists of tuples, tuples, tuples of tuples, tuples
Chris@87 559 of lists and ndarrays. Success requires no NaNs or Infs.
Chris@87 560 dtype : data-type, optional
Chris@87 561 By default, the data-type is inferred from the input data.
Chris@87 562 order : {'C', 'F'}, optional
Chris@87 563 Whether to use row-major ('C') or column-major ('FORTRAN') memory
Chris@87 564 representation. Defaults to 'C'.
Chris@87 565
Chris@87 566 Returns
Chris@87 567 -------
Chris@87 568 out : ndarray
Chris@87 569 Array interpretation of `a`. No copy is performed if the input
Chris@87 570 is already an ndarray. If `a` is a subclass of ndarray, a base
Chris@87 571 class ndarray is returned.
Chris@87 572
Chris@87 573 Raises
Chris@87 574 ------
Chris@87 575 ValueError
Chris@87 576 Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity).
Chris@87 577
Chris@87 578 See Also
Chris@87 579 --------
Chris@87 580 asarray : Create and array.
Chris@87 581 asanyarray : Similar function which passes through subclasses.
Chris@87 582 ascontiguousarray : Convert input to a contiguous array.
Chris@87 583 asfarray : Convert input to a floating point ndarray.
Chris@87 584 asfortranarray : Convert input to an ndarray with column-major
Chris@87 585 memory order.
Chris@87 586 fromiter : Create an array from an iterator.
Chris@87 587 fromfunction : Construct an array by executing a function on grid
Chris@87 588 positions.
Chris@87 589
Chris@87 590 Examples
Chris@87 591 --------
Chris@87 592 Convert a list into an array. If all elements are finite
Chris@87 593 ``asarray_chkfinite`` is identical to ``asarray``.
Chris@87 594
Chris@87 595 >>> a = [1, 2]
Chris@87 596 >>> np.asarray_chkfinite(a, dtype=float)
Chris@87 597 array([1., 2.])
Chris@87 598
Chris@87 599 Raises ValueError if array_like contains Nans or Infs.
Chris@87 600
Chris@87 601 >>> a = [1, 2, np.inf]
Chris@87 602 >>> try:
Chris@87 603 ... np.asarray_chkfinite(a)
Chris@87 604 ... except ValueError:
Chris@87 605 ... print 'ValueError'
Chris@87 606 ...
Chris@87 607 ValueError
Chris@87 608
Chris@87 609 """
Chris@87 610 a = asarray(a, dtype=dtype, order=order)
Chris@87 611 if a.dtype.char in typecodes['AllFloat'] and not np.isfinite(a).all():
Chris@87 612 raise ValueError(
Chris@87 613 "array must not contain infs or NaNs")
Chris@87 614 return a
Chris@87 615
Chris@87 616
Chris@87 617 def piecewise(x, condlist, funclist, *args, **kw):
Chris@87 618 """
Chris@87 619 Evaluate a piecewise-defined function.
Chris@87 620
Chris@87 621 Given a set of conditions and corresponding functions, evaluate each
Chris@87 622 function on the input data wherever its condition is true.
Chris@87 623
Chris@87 624 Parameters
Chris@87 625 ----------
Chris@87 626 x : ndarray
Chris@87 627 The input domain.
Chris@87 628 condlist : list of bool arrays
Chris@87 629 Each boolean array corresponds to a function in `funclist`. Wherever
Chris@87 630 `condlist[i]` is True, `funclist[i](x)` is used as the output value.
Chris@87 631
Chris@87 632 Each boolean array in `condlist` selects a piece of `x`,
Chris@87 633 and should therefore be of the same shape as `x`.
Chris@87 634
Chris@87 635 The length of `condlist` must correspond to that of `funclist`.
Chris@87 636 If one extra function is given, i.e. if
Chris@87 637 ``len(funclist) - len(condlist) == 1``, then that extra function
Chris@87 638 is the default value, used wherever all conditions are false.
Chris@87 639 funclist : list of callables, f(x,*args,**kw), or scalars
Chris@87 640 Each function is evaluated over `x` wherever its corresponding
Chris@87 641 condition is True. It should take an array as input and give an array
Chris@87 642 or a scalar value as output. If, instead of a callable,
Chris@87 643 a scalar is provided then a constant function (``lambda x: scalar``) is
Chris@87 644 assumed.
Chris@87 645 args : tuple, optional
Chris@87 646 Any further arguments given to `piecewise` are passed to the functions
Chris@87 647 upon execution, i.e., if called ``piecewise(..., ..., 1, 'a')``, then
Chris@87 648 each function is called as ``f(x, 1, 'a')``.
Chris@87 649 kw : dict, optional
Chris@87 650 Keyword arguments used in calling `piecewise` are passed to the
Chris@87 651 functions upon execution, i.e., if called
Chris@87 652 ``piecewise(..., ..., lambda=1)``, then each function is called as
Chris@87 653 ``f(x, lambda=1)``.
Chris@87 654
Chris@87 655 Returns
Chris@87 656 -------
Chris@87 657 out : ndarray
Chris@87 658 The output is the same shape and type as x and is found by
Chris@87 659 calling the functions in `funclist` on the appropriate portions of `x`,
Chris@87 660 as defined by the boolean arrays in `condlist`. Portions not covered
Chris@87 661 by any condition have a default value of 0.
Chris@87 662
Chris@87 663
Chris@87 664 See Also
Chris@87 665 --------
Chris@87 666 choose, select, where
Chris@87 667
Chris@87 668 Notes
Chris@87 669 -----
Chris@87 670 This is similar to choose or select, except that functions are
Chris@87 671 evaluated on elements of `x` that satisfy the corresponding condition from
Chris@87 672 `condlist`.
Chris@87 673
Chris@87 674 The result is::
Chris@87 675
Chris@87 676 |--
Chris@87 677 |funclist[0](x[condlist[0]])
Chris@87 678 out = |funclist[1](x[condlist[1]])
Chris@87 679 |...
Chris@87 680 |funclist[n2](x[condlist[n2]])
Chris@87 681 |--
Chris@87 682
Chris@87 683 Examples
Chris@87 684 --------
Chris@87 685 Define the sigma function, which is -1 for ``x < 0`` and +1 for ``x >= 0``.
Chris@87 686
Chris@87 687 >>> x = np.linspace(-2.5, 2.5, 6)
Chris@87 688 >>> np.piecewise(x, [x < 0, x >= 0], [-1, 1])
Chris@87 689 array([-1., -1., -1., 1., 1., 1.])
Chris@87 690
Chris@87 691 Define the absolute value, which is ``-x`` for ``x <0`` and ``x`` for
Chris@87 692 ``x >= 0``.
Chris@87 693
Chris@87 694 >>> np.piecewise(x, [x < 0, x >= 0], [lambda x: -x, lambda x: x])
Chris@87 695 array([ 2.5, 1.5, 0.5, 0.5, 1.5, 2.5])
Chris@87 696
Chris@87 697 """
Chris@87 698 x = asanyarray(x)
Chris@87 699 n2 = len(funclist)
Chris@87 700 if (isscalar(condlist) or not (isinstance(condlist[0], list) or
Chris@87 701 isinstance(condlist[0], ndarray))):
Chris@87 702 condlist = [condlist]
Chris@87 703 condlist = array(condlist, dtype=bool)
Chris@87 704 n = len(condlist)
Chris@87 705 # This is a hack to work around problems with NumPy's
Chris@87 706 # handling of 0-d arrays and boolean indexing with
Chris@87 707 # numpy.bool_ scalars
Chris@87 708 zerod = False
Chris@87 709 if x.ndim == 0:
Chris@87 710 x = x[None]
Chris@87 711 zerod = True
Chris@87 712 if condlist.shape[-1] != 1:
Chris@87 713 condlist = condlist.T
Chris@87 714 if n == n2 - 1: # compute the "otherwise" condition.
Chris@87 715 totlist = np.logical_or.reduce(condlist, axis=0)
Chris@87 716 condlist = np.vstack([condlist, ~totlist])
Chris@87 717 n += 1
Chris@87 718 if (n != n2):
Chris@87 719 raise ValueError(
Chris@87 720 "function list and condition list must be the same")
Chris@87 721
Chris@87 722 y = zeros(x.shape, x.dtype)
Chris@87 723 for k in range(n):
Chris@87 724 item = funclist[k]
Chris@87 725 if not isinstance(item, collections.Callable):
Chris@87 726 y[condlist[k]] = item
Chris@87 727 else:
Chris@87 728 vals = x[condlist[k]]
Chris@87 729 if vals.size > 0:
Chris@87 730 y[condlist[k]] = item(vals, *args, **kw)
Chris@87 731 if zerod:
Chris@87 732 y = y.squeeze()
Chris@87 733 return y
Chris@87 734
Chris@87 735
Chris@87 736 def select(condlist, choicelist, default=0):
Chris@87 737 """
Chris@87 738 Return an array drawn from elements in choicelist, depending on conditions.
Chris@87 739
Chris@87 740 Parameters
Chris@87 741 ----------
Chris@87 742 condlist : list of bool ndarrays
Chris@87 743 The list of conditions which determine from which array in `choicelist`
Chris@87 744 the output elements are taken. When multiple conditions are satisfied,
Chris@87 745 the first one encountered in `condlist` is used.
Chris@87 746 choicelist : list of ndarrays
Chris@87 747 The list of arrays from which the output elements are taken. It has
Chris@87 748 to be of the same length as `condlist`.
Chris@87 749 default : scalar, optional
Chris@87 750 The element inserted in `output` when all conditions evaluate to False.
Chris@87 751
Chris@87 752 Returns
Chris@87 753 -------
Chris@87 754 output : ndarray
Chris@87 755 The output at position m is the m-th element of the array in
Chris@87 756 `choicelist` where the m-th element of the corresponding array in
Chris@87 757 `condlist` is True.
Chris@87 758
Chris@87 759 See Also
Chris@87 760 --------
Chris@87 761 where : Return elements from one of two arrays depending on condition.
Chris@87 762 take, choose, compress, diag, diagonal
Chris@87 763
Chris@87 764 Examples
Chris@87 765 --------
Chris@87 766 >>> x = np.arange(10)
Chris@87 767 >>> condlist = [x<3, x>5]
Chris@87 768 >>> choicelist = [x, x**2]
Chris@87 769 >>> np.select(condlist, choicelist)
Chris@87 770 array([ 0, 1, 2, 0, 0, 0, 36, 49, 64, 81])
Chris@87 771
Chris@87 772 """
Chris@87 773 # Check the size of condlist and choicelist are the same, or abort.
Chris@87 774 if len(condlist) != len(choicelist):
Chris@87 775 raise ValueError(
Chris@87 776 'list of cases must be same length as list of conditions')
Chris@87 777
Chris@87 778 # Now that the dtype is known, handle the deprecated select([], []) case
Chris@87 779 if len(condlist) == 0:
Chris@87 780 warnings.warn("select with an empty condition list is not possible"
Chris@87 781 "and will be deprecated",
Chris@87 782 DeprecationWarning)
Chris@87 783 return np.asarray(default)[()]
Chris@87 784
Chris@87 785 choicelist = [np.asarray(choice) for choice in choicelist]
Chris@87 786 choicelist.append(np.asarray(default))
Chris@87 787
Chris@87 788 # need to get the result type before broadcasting for correct scalar
Chris@87 789 # behaviour
Chris@87 790 dtype = np.result_type(*choicelist)
Chris@87 791
Chris@87 792 # Convert conditions to arrays and broadcast conditions and choices
Chris@87 793 # as the shape is needed for the result. Doing it seperatly optimizes
Chris@87 794 # for example when all choices are scalars.
Chris@87 795 condlist = np.broadcast_arrays(*condlist)
Chris@87 796 choicelist = np.broadcast_arrays(*choicelist)
Chris@87 797
Chris@87 798 # If cond array is not an ndarray in boolean format or scalar bool, abort.
Chris@87 799 deprecated_ints = False
Chris@87 800 for i in range(len(condlist)):
Chris@87 801 cond = condlist[i]
Chris@87 802 if cond.dtype.type is not np.bool_:
Chris@87 803 if np.issubdtype(cond.dtype, np.integer):
Chris@87 804 # A previous implementation accepted int ndarrays accidentally.
Chris@87 805 # Supported here deliberately, but deprecated.
Chris@87 806 condlist[i] = condlist[i].astype(bool)
Chris@87 807 deprecated_ints = True
Chris@87 808 else:
Chris@87 809 raise ValueError(
Chris@87 810 'invalid entry in choicelist: should be boolean ndarray')
Chris@87 811
Chris@87 812 if deprecated_ints:
Chris@87 813 msg = "select condlists containing integer ndarrays is deprecated " \
Chris@87 814 "and will be removed in the future. Use `.astype(bool)` to " \
Chris@87 815 "convert to bools."
Chris@87 816 warnings.warn(msg, DeprecationWarning)
Chris@87 817
Chris@87 818 if choicelist[0].ndim == 0:
Chris@87 819 # This may be common, so avoid the call.
Chris@87 820 result_shape = condlist[0].shape
Chris@87 821 else:
Chris@87 822 result_shape = np.broadcast_arrays(condlist[0], choicelist[0])[0].shape
Chris@87 823
Chris@87 824 result = np.full(result_shape, choicelist[-1], dtype)
Chris@87 825
Chris@87 826 # Use np.copyto to burn each choicelist array onto result, using the
Chris@87 827 # corresponding condlist as a boolean mask. This is done in reverse
Chris@87 828 # order since the first choice should take precedence.
Chris@87 829 choicelist = choicelist[-2::-1]
Chris@87 830 condlist = condlist[::-1]
Chris@87 831 for choice, cond in zip(choicelist, condlist):
Chris@87 832 np.copyto(result, choice, where=cond)
Chris@87 833
Chris@87 834 return result
Chris@87 835
Chris@87 836
Chris@87 837 def copy(a, order='K'):
Chris@87 838 """
Chris@87 839 Return an array copy of the given object.
Chris@87 840
Chris@87 841 Parameters
Chris@87 842 ----------
Chris@87 843 a : array_like
Chris@87 844 Input data.
Chris@87 845 order : {'C', 'F', 'A', 'K'}, optional
Chris@87 846 Controls the memory layout of the copy. 'C' means C-order,
Chris@87 847 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
Chris@87 848 'C' otherwise. 'K' means match the layout of `a` as closely
Chris@87 849 as possible. (Note that this function and :meth:ndarray.copy are very
Chris@87 850 similar, but have different default values for their order=
Chris@87 851 arguments.)
Chris@87 852
Chris@87 853 Returns
Chris@87 854 -------
Chris@87 855 arr : ndarray
Chris@87 856 Array interpretation of `a`.
Chris@87 857
Chris@87 858 Notes
Chris@87 859 -----
Chris@87 860 This is equivalent to
Chris@87 861
Chris@87 862 >>> np.array(a, copy=True) #doctest: +SKIP
Chris@87 863
Chris@87 864 Examples
Chris@87 865 --------
Chris@87 866 Create an array x, with a reference y and a copy z:
Chris@87 867
Chris@87 868 >>> x = np.array([1, 2, 3])
Chris@87 869 >>> y = x
Chris@87 870 >>> z = np.copy(x)
Chris@87 871
Chris@87 872 Note that, when we modify x, y changes, but not z:
Chris@87 873
Chris@87 874 >>> x[0] = 10
Chris@87 875 >>> x[0] == y[0]
Chris@87 876 True
Chris@87 877 >>> x[0] == z[0]
Chris@87 878 False
Chris@87 879
Chris@87 880 """
Chris@87 881 return array(a, order=order, copy=True)
Chris@87 882
Chris@87 883 # Basic operations
Chris@87 884
Chris@87 885
Chris@87 886 def gradient(f, *varargs, **kwargs):
Chris@87 887 """
Chris@87 888 Return the gradient of an N-dimensional array.
Chris@87 889
Chris@87 890 The gradient is computed using second order accurate central differences
Chris@87 891 in the interior and either first differences or second order accurate
Chris@87 892 one-sides (forward or backwards) differences at the boundaries. The
Chris@87 893 returned gradient hence has the same shape as the input array.
Chris@87 894
Chris@87 895 Parameters
Chris@87 896 ----------
Chris@87 897 f : array_like
Chris@87 898 An N-dimensional array containing samples of a scalar function.
Chris@87 899 varargs : list of scalar, optional
Chris@87 900 N scalars specifying the sample distances for each dimension,
Chris@87 901 i.e. `dx`, `dy`, `dz`, ... Default distance: 1.
Chris@87 902 edge_order : {1, 2}, optional
Chris@87 903 Gradient is calculated using N\ :sup:`th` order accurate differences
Chris@87 904 at the boundaries. Default: 1.
Chris@87 905
Chris@87 906 .. versionadded:: 1.9.1
Chris@87 907
Chris@87 908 Returns
Chris@87 909 -------
Chris@87 910 gradient : ndarray
Chris@87 911 N arrays of the same shape as `f` giving the derivative of `f` with
Chris@87 912 respect to each dimension.
Chris@87 913
Chris@87 914 Examples
Chris@87 915 --------
Chris@87 916 >>> x = np.array([1, 2, 4, 7, 11, 16], dtype=np.float)
Chris@87 917 >>> np.gradient(x)
Chris@87 918 array([ 1. , 1.5, 2.5, 3.5, 4.5, 5. ])
Chris@87 919 >>> np.gradient(x, 2)
Chris@87 920 array([ 0.5 , 0.75, 1.25, 1.75, 2.25, 2.5 ])
Chris@87 921
Chris@87 922 >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float))
Chris@87 923 [array([[ 2., 2., -1.],
Chris@87 924 [ 2., 2., -1.]]), array([[ 1. , 2.5, 4. ],
Chris@87 925 [ 1. , 1. , 1. ]])]
Chris@87 926
Chris@87 927 >>> x = np.array([0, 1, 2, 3, 4])
Chris@87 928 >>> dx = np.gradient(x)
Chris@87 929 >>> y = x**2
Chris@87 930 >>> np.gradient(y, dx, edge_order=2)
Chris@87 931 array([-0., 2., 4., 6., 8.])
Chris@87 932 """
Chris@87 933 f = np.asanyarray(f)
Chris@87 934 N = len(f.shape) # number of dimensions
Chris@87 935 n = len(varargs)
Chris@87 936 if n == 0:
Chris@87 937 dx = [1.0]*N
Chris@87 938 elif n == 1:
Chris@87 939 dx = [varargs[0]]*N
Chris@87 940 elif n == N:
Chris@87 941 dx = list(varargs)
Chris@87 942 else:
Chris@87 943 raise SyntaxError(
Chris@87 944 "invalid number of arguments")
Chris@87 945
Chris@87 946 edge_order = kwargs.pop('edge_order', 1)
Chris@87 947 if kwargs:
Chris@87 948 raise TypeError('"{}" are not valid keyword arguments.'.format(
Chris@87 949 '", "'.join(kwargs.keys())))
Chris@87 950 if edge_order > 2:
Chris@87 951 raise ValueError("'edge_order' greater than 2 not supported")
Chris@87 952
Chris@87 953 # use central differences on interior and one-sided differences on the
Chris@87 954 # endpoints. This preserves second order-accuracy over the full domain.
Chris@87 955
Chris@87 956 outvals = []
Chris@87 957
Chris@87 958 # create slice objects --- initially all are [:, :, ..., :]
Chris@87 959 slice1 = [slice(None)]*N
Chris@87 960 slice2 = [slice(None)]*N
Chris@87 961 slice3 = [slice(None)]*N
Chris@87 962 slice4 = [slice(None)]*N
Chris@87 963
Chris@87 964 otype = f.dtype.char
Chris@87 965 if otype not in ['f', 'd', 'F', 'D', 'm', 'M']:
Chris@87 966 otype = 'd'
Chris@87 967
Chris@87 968 # Difference of datetime64 elements results in timedelta64
Chris@87 969 if otype == 'M':
Chris@87 970 # Need to use the full dtype name because it contains unit information
Chris@87 971 otype = f.dtype.name.replace('datetime', 'timedelta')
Chris@87 972 elif otype == 'm':
Chris@87 973 # Needs to keep the specific units, can't be a general unit
Chris@87 974 otype = f.dtype
Chris@87 975
Chris@87 976 # Convert datetime64 data into ints. Make dummy variable `y`
Chris@87 977 # that is a view of ints if the data is datetime64, otherwise
Chris@87 978 # just set y equal to the the array `f`.
Chris@87 979 if f.dtype.char in ["M", "m"]:
Chris@87 980 y = f.view('int64')
Chris@87 981 else:
Chris@87 982 y = f
Chris@87 983
Chris@87 984 for axis in range(N):
Chris@87 985
Chris@87 986 if y.shape[axis] < 2:
Chris@87 987 raise ValueError(
Chris@87 988 "Shape of array too small to calculate a numerical gradient, "
Chris@87 989 "at least two elements are required.")
Chris@87 990
Chris@87 991 # Numerical differentiation: 1st order edges, 2nd order interior
Chris@87 992 if y.shape[axis] == 2 or edge_order == 1:
Chris@87 993 # Use first order differences for time data
Chris@87 994 out = np.empty_like(y, dtype=otype)
Chris@87 995
Chris@87 996 slice1[axis] = slice(1, -1)
Chris@87 997 slice2[axis] = slice(2, None)
Chris@87 998 slice3[axis] = slice(None, -2)
Chris@87 999 # 1D equivalent -- out[1:-1] = (y[2:] - y[:-2])/2.0
Chris@87 1000 out[slice1] = (y[slice2] - y[slice3])/2.0
Chris@87 1001
Chris@87 1002 slice1[axis] = 0
Chris@87 1003 slice2[axis] = 1
Chris@87 1004 slice3[axis] = 0
Chris@87 1005 # 1D equivalent -- out[0] = (y[1] - y[0])
Chris@87 1006 out[slice1] = (y[slice2] - y[slice3])
Chris@87 1007
Chris@87 1008 slice1[axis] = -1
Chris@87 1009 slice2[axis] = -1
Chris@87 1010 slice3[axis] = -2
Chris@87 1011 # 1D equivalent -- out[-1] = (y[-1] - y[-2])
Chris@87 1012 out[slice1] = (y[slice2] - y[slice3])
Chris@87 1013
Chris@87 1014 # Numerical differentiation: 2st order edges, 2nd order interior
Chris@87 1015 else:
Chris@87 1016 # Use second order differences where possible
Chris@87 1017 out = np.empty_like(y, dtype=otype)
Chris@87 1018
Chris@87 1019 slice1[axis] = slice(1, -1)
Chris@87 1020 slice2[axis] = slice(2, None)
Chris@87 1021 slice3[axis] = slice(None, -2)
Chris@87 1022 # 1D equivalent -- out[1:-1] = (y[2:] - y[:-2])/2.0
Chris@87 1023 out[slice1] = (y[slice2] - y[slice3])/2.0
Chris@87 1024
Chris@87 1025 slice1[axis] = 0
Chris@87 1026 slice2[axis] = 0
Chris@87 1027 slice3[axis] = 1
Chris@87 1028 slice4[axis] = 2
Chris@87 1029 # 1D equivalent -- out[0] = -(3*y[0] - 4*y[1] + y[2]) / 2.0
Chris@87 1030 out[slice1] = -(3.0*y[slice2] - 4.0*y[slice3] + y[slice4])/2.0
Chris@87 1031
Chris@87 1032 slice1[axis] = -1
Chris@87 1033 slice2[axis] = -1
Chris@87 1034 slice3[axis] = -2
Chris@87 1035 slice4[axis] = -3
Chris@87 1036 # 1D equivalent -- out[-1] = (3*y[-1] - 4*y[-2] + y[-3])
Chris@87 1037 out[slice1] = (3.0*y[slice2] - 4.0*y[slice3] + y[slice4])/2.0
Chris@87 1038
Chris@87 1039 # divide by step size
Chris@87 1040 out /= dx[axis]
Chris@87 1041 outvals.append(out)
Chris@87 1042
Chris@87 1043 # reset the slice object in this dimension to ":"
Chris@87 1044 slice1[axis] = slice(None)
Chris@87 1045 slice2[axis] = slice(None)
Chris@87 1046 slice3[axis] = slice(None)
Chris@87 1047 slice4[axis] = slice(None)
Chris@87 1048
Chris@87 1049 if N == 1:
Chris@87 1050 return outvals[0]
Chris@87 1051 else:
Chris@87 1052 return outvals
Chris@87 1053
Chris@87 1054
Chris@87 1055 def diff(a, n=1, axis=-1):
Chris@87 1056 """
Chris@87 1057 Calculate the n-th order discrete difference along given axis.
Chris@87 1058
Chris@87 1059 The first order difference is given by ``out[n] = a[n+1] - a[n]`` along
Chris@87 1060 the given axis, higher order differences are calculated by using `diff`
Chris@87 1061 recursively.
Chris@87 1062
Chris@87 1063 Parameters
Chris@87 1064 ----------
Chris@87 1065 a : array_like
Chris@87 1066 Input array
Chris@87 1067 n : int, optional
Chris@87 1068 The number of times values are differenced.
Chris@87 1069 axis : int, optional
Chris@87 1070 The axis along which the difference is taken, default is the last axis.
Chris@87 1071
Chris@87 1072 Returns
Chris@87 1073 -------
Chris@87 1074 diff : ndarray
Chris@87 1075 The `n` order differences. The shape of the output is the same as `a`
Chris@87 1076 except along `axis` where the dimension is smaller by `n`.
Chris@87 1077
Chris@87 1078 See Also
Chris@87 1079 --------
Chris@87 1080 gradient, ediff1d, cumsum
Chris@87 1081
Chris@87 1082 Examples
Chris@87 1083 --------
Chris@87 1084 >>> x = np.array([1, 2, 4, 7, 0])
Chris@87 1085 >>> np.diff(x)
Chris@87 1086 array([ 1, 2, 3, -7])
Chris@87 1087 >>> np.diff(x, n=2)
Chris@87 1088 array([ 1, 1, -10])
Chris@87 1089
Chris@87 1090 >>> x = np.array([[1, 3, 6, 10], [0, 5, 6, 8]])
Chris@87 1091 >>> np.diff(x)
Chris@87 1092 array([[2, 3, 4],
Chris@87 1093 [5, 1, 2]])
Chris@87 1094 >>> np.diff(x, axis=0)
Chris@87 1095 array([[-1, 2, 0, -2]])
Chris@87 1096
Chris@87 1097 """
Chris@87 1098 if n == 0:
Chris@87 1099 return a
Chris@87 1100 if n < 0:
Chris@87 1101 raise ValueError(
Chris@87 1102 "order must be non-negative but got " + repr(n))
Chris@87 1103 a = asanyarray(a)
Chris@87 1104 nd = len(a.shape)
Chris@87 1105 slice1 = [slice(None)]*nd
Chris@87 1106 slice2 = [slice(None)]*nd
Chris@87 1107 slice1[axis] = slice(1, None)
Chris@87 1108 slice2[axis] = slice(None, -1)
Chris@87 1109 slice1 = tuple(slice1)
Chris@87 1110 slice2 = tuple(slice2)
Chris@87 1111 if n > 1:
Chris@87 1112 return diff(a[slice1]-a[slice2], n-1, axis=axis)
Chris@87 1113 else:
Chris@87 1114 return a[slice1]-a[slice2]
Chris@87 1115
Chris@87 1116
Chris@87 1117 def interp(x, xp, fp, left=None, right=None):
Chris@87 1118 """
Chris@87 1119 One-dimensional linear interpolation.
Chris@87 1120
Chris@87 1121 Returns the one-dimensional piecewise linear interpolant to a function
Chris@87 1122 with given values at discrete data-points.
Chris@87 1123
Chris@87 1124 Parameters
Chris@87 1125 ----------
Chris@87 1126 x : array_like
Chris@87 1127 The x-coordinates of the interpolated values.
Chris@87 1128
Chris@87 1129 xp : 1-D sequence of floats
Chris@87 1130 The x-coordinates of the data points, must be increasing.
Chris@87 1131
Chris@87 1132 fp : 1-D sequence of floats
Chris@87 1133 The y-coordinates of the data points, same length as `xp`.
Chris@87 1134
Chris@87 1135 left : float, optional
Chris@87 1136 Value to return for `x < xp[0]`, default is `fp[0]`.
Chris@87 1137
Chris@87 1138 right : float, optional
Chris@87 1139 Value to return for `x > xp[-1]`, default is `fp[-1]`.
Chris@87 1140
Chris@87 1141 Returns
Chris@87 1142 -------
Chris@87 1143 y : {float, ndarray}
Chris@87 1144 The interpolated values, same shape as `x`.
Chris@87 1145
Chris@87 1146 Raises
Chris@87 1147 ------
Chris@87 1148 ValueError
Chris@87 1149 If `xp` and `fp` have different length
Chris@87 1150
Chris@87 1151 Notes
Chris@87 1152 -----
Chris@87 1153 Does not check that the x-coordinate sequence `xp` is increasing.
Chris@87 1154 If `xp` is not increasing, the results are nonsense.
Chris@87 1155 A simple check for increasing is::
Chris@87 1156
Chris@87 1157 np.all(np.diff(xp) > 0)
Chris@87 1158
Chris@87 1159
Chris@87 1160 Examples
Chris@87 1161 --------
Chris@87 1162 >>> xp = [1, 2, 3]
Chris@87 1163 >>> fp = [3, 2, 0]
Chris@87 1164 >>> np.interp(2.5, xp, fp)
Chris@87 1165 1.0
Chris@87 1166 >>> np.interp([0, 1, 1.5, 2.72, 3.14], xp, fp)
Chris@87 1167 array([ 3. , 3. , 2.5 , 0.56, 0. ])
Chris@87 1168 >>> UNDEF = -99.0
Chris@87 1169 >>> np.interp(3.14, xp, fp, right=UNDEF)
Chris@87 1170 -99.0
Chris@87 1171
Chris@87 1172 Plot an interpolant to the sine function:
Chris@87 1173
Chris@87 1174 >>> x = np.linspace(0, 2*np.pi, 10)
Chris@87 1175 >>> y = np.sin(x)
Chris@87 1176 >>> xvals = np.linspace(0, 2*np.pi, 50)
Chris@87 1177 >>> yinterp = np.interp(xvals, x, y)
Chris@87 1178 >>> import matplotlib.pyplot as plt
Chris@87 1179 >>> plt.plot(x, y, 'o')
Chris@87 1180 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 1181 >>> plt.plot(xvals, yinterp, '-x')
Chris@87 1182 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 1183 >>> plt.show()
Chris@87 1184
Chris@87 1185 """
Chris@87 1186 if isinstance(x, (float, int, number)):
Chris@87 1187 return compiled_interp([x], xp, fp, left, right).item()
Chris@87 1188 elif isinstance(x, np.ndarray) and x.ndim == 0:
Chris@87 1189 return compiled_interp([x], xp, fp, left, right).item()
Chris@87 1190 else:
Chris@87 1191 return compiled_interp(x, xp, fp, left, right)
Chris@87 1192
Chris@87 1193
Chris@87 1194 def angle(z, deg=0):
Chris@87 1195 """
Chris@87 1196 Return the angle of the complex argument.
Chris@87 1197
Chris@87 1198 Parameters
Chris@87 1199 ----------
Chris@87 1200 z : array_like
Chris@87 1201 A complex number or sequence of complex numbers.
Chris@87 1202 deg : bool, optional
Chris@87 1203 Return angle in degrees if True, radians if False (default).
Chris@87 1204
Chris@87 1205 Returns
Chris@87 1206 -------
Chris@87 1207 angle : {ndarray, scalar}
Chris@87 1208 The counterclockwise angle from the positive real axis on
Chris@87 1209 the complex plane, with dtype as numpy.float64.
Chris@87 1210
Chris@87 1211 See Also
Chris@87 1212 --------
Chris@87 1213 arctan2
Chris@87 1214 absolute
Chris@87 1215
Chris@87 1216
Chris@87 1217
Chris@87 1218 Examples
Chris@87 1219 --------
Chris@87 1220 >>> np.angle([1.0, 1.0j, 1+1j]) # in radians
Chris@87 1221 array([ 0. , 1.57079633, 0.78539816])
Chris@87 1222 >>> np.angle(1+1j, deg=True) # in degrees
Chris@87 1223 45.0
Chris@87 1224
Chris@87 1225 """
Chris@87 1226 if deg:
Chris@87 1227 fact = 180/pi
Chris@87 1228 else:
Chris@87 1229 fact = 1.0
Chris@87 1230 z = asarray(z)
Chris@87 1231 if (issubclass(z.dtype.type, _nx.complexfloating)):
Chris@87 1232 zimag = z.imag
Chris@87 1233 zreal = z.real
Chris@87 1234 else:
Chris@87 1235 zimag = 0
Chris@87 1236 zreal = z
Chris@87 1237 return arctan2(zimag, zreal) * fact
Chris@87 1238
Chris@87 1239
Chris@87 1240 def unwrap(p, discont=pi, axis=-1):
Chris@87 1241 """
Chris@87 1242 Unwrap by changing deltas between values to 2*pi complement.
Chris@87 1243
Chris@87 1244 Unwrap radian phase `p` by changing absolute jumps greater than
Chris@87 1245 `discont` to their 2*pi complement along the given axis.
Chris@87 1246
Chris@87 1247 Parameters
Chris@87 1248 ----------
Chris@87 1249 p : array_like
Chris@87 1250 Input array.
Chris@87 1251 discont : float, optional
Chris@87 1252 Maximum discontinuity between values, default is ``pi``.
Chris@87 1253 axis : int, optional
Chris@87 1254 Axis along which unwrap will operate, default is the last axis.
Chris@87 1255
Chris@87 1256 Returns
Chris@87 1257 -------
Chris@87 1258 out : ndarray
Chris@87 1259 Output array.
Chris@87 1260
Chris@87 1261 See Also
Chris@87 1262 --------
Chris@87 1263 rad2deg, deg2rad
Chris@87 1264
Chris@87 1265 Notes
Chris@87 1266 -----
Chris@87 1267 If the discontinuity in `p` is smaller than ``pi``, but larger than
Chris@87 1268 `discont`, no unwrapping is done because taking the 2*pi complement
Chris@87 1269 would only make the discontinuity larger.
Chris@87 1270
Chris@87 1271 Examples
Chris@87 1272 --------
Chris@87 1273 >>> phase = np.linspace(0, np.pi, num=5)
Chris@87 1274 >>> phase[3:] += np.pi
Chris@87 1275 >>> phase
Chris@87 1276 array([ 0. , 0.78539816, 1.57079633, 5.49778714, 6.28318531])
Chris@87 1277 >>> np.unwrap(phase)
Chris@87 1278 array([ 0. , 0.78539816, 1.57079633, -0.78539816, 0. ])
Chris@87 1279
Chris@87 1280 """
Chris@87 1281 p = asarray(p)
Chris@87 1282 nd = len(p.shape)
Chris@87 1283 dd = diff(p, axis=axis)
Chris@87 1284 slice1 = [slice(None, None)]*nd # full slices
Chris@87 1285 slice1[axis] = slice(1, None)
Chris@87 1286 ddmod = mod(dd + pi, 2*pi) - pi
Chris@87 1287 _nx.copyto(ddmod, pi, where=(ddmod == -pi) & (dd > 0))
Chris@87 1288 ph_correct = ddmod - dd
Chris@87 1289 _nx.copyto(ph_correct, 0, where=abs(dd) < discont)
Chris@87 1290 up = array(p, copy=True, dtype='d')
Chris@87 1291 up[slice1] = p[slice1] + ph_correct.cumsum(axis)
Chris@87 1292 return up
Chris@87 1293
Chris@87 1294
Chris@87 1295 def sort_complex(a):
Chris@87 1296 """
Chris@87 1297 Sort a complex array using the real part first, then the imaginary part.
Chris@87 1298
Chris@87 1299 Parameters
Chris@87 1300 ----------
Chris@87 1301 a : array_like
Chris@87 1302 Input array
Chris@87 1303
Chris@87 1304 Returns
Chris@87 1305 -------
Chris@87 1306 out : complex ndarray
Chris@87 1307 Always returns a sorted complex array.
Chris@87 1308
Chris@87 1309 Examples
Chris@87 1310 --------
Chris@87 1311 >>> np.sort_complex([5, 3, 6, 2, 1])
Chris@87 1312 array([ 1.+0.j, 2.+0.j, 3.+0.j, 5.+0.j, 6.+0.j])
Chris@87 1313
Chris@87 1314 >>> np.sort_complex([1 + 2j, 2 - 1j, 3 - 2j, 3 - 3j, 3 + 5j])
Chris@87 1315 array([ 1.+2.j, 2.-1.j, 3.-3.j, 3.-2.j, 3.+5.j])
Chris@87 1316
Chris@87 1317 """
Chris@87 1318 b = array(a, copy=True)
Chris@87 1319 b.sort()
Chris@87 1320 if not issubclass(b.dtype.type, _nx.complexfloating):
Chris@87 1321 if b.dtype.char in 'bhBH':
Chris@87 1322 return b.astype('F')
Chris@87 1323 elif b.dtype.char == 'g':
Chris@87 1324 return b.astype('G')
Chris@87 1325 else:
Chris@87 1326 return b.astype('D')
Chris@87 1327 else:
Chris@87 1328 return b
Chris@87 1329
Chris@87 1330
Chris@87 1331 def trim_zeros(filt, trim='fb'):
Chris@87 1332 """
Chris@87 1333 Trim the leading and/or trailing zeros from a 1-D array or sequence.
Chris@87 1334
Chris@87 1335 Parameters
Chris@87 1336 ----------
Chris@87 1337 filt : 1-D array or sequence
Chris@87 1338 Input array.
Chris@87 1339 trim : str, optional
Chris@87 1340 A string with 'f' representing trim from front and 'b' to trim from
Chris@87 1341 back. Default is 'fb', trim zeros from both front and back of the
Chris@87 1342 array.
Chris@87 1343
Chris@87 1344 Returns
Chris@87 1345 -------
Chris@87 1346 trimmed : 1-D array or sequence
Chris@87 1347 The result of trimming the input. The input data type is preserved.
Chris@87 1348
Chris@87 1349 Examples
Chris@87 1350 --------
Chris@87 1351 >>> a = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0))
Chris@87 1352 >>> np.trim_zeros(a)
Chris@87 1353 array([1, 2, 3, 0, 2, 1])
Chris@87 1354
Chris@87 1355 >>> np.trim_zeros(a, 'b')
Chris@87 1356 array([0, 0, 0, 1, 2, 3, 0, 2, 1])
Chris@87 1357
Chris@87 1358 The input data type is preserved, list/tuple in means list/tuple out.
Chris@87 1359
Chris@87 1360 >>> np.trim_zeros([0, 1, 2, 0])
Chris@87 1361 [1, 2]
Chris@87 1362
Chris@87 1363 """
Chris@87 1364 first = 0
Chris@87 1365 trim = trim.upper()
Chris@87 1366 if 'F' in trim:
Chris@87 1367 for i in filt:
Chris@87 1368 if i != 0.:
Chris@87 1369 break
Chris@87 1370 else:
Chris@87 1371 first = first + 1
Chris@87 1372 last = len(filt)
Chris@87 1373 if 'B' in trim:
Chris@87 1374 for i in filt[::-1]:
Chris@87 1375 if i != 0.:
Chris@87 1376 break
Chris@87 1377 else:
Chris@87 1378 last = last - 1
Chris@87 1379 return filt[first:last]
Chris@87 1380
Chris@87 1381
Chris@87 1382 @deprecate
Chris@87 1383 def unique(x):
Chris@87 1384 """
Chris@87 1385 This function is deprecated. Use numpy.lib.arraysetops.unique()
Chris@87 1386 instead.
Chris@87 1387 """
Chris@87 1388 try:
Chris@87 1389 tmp = x.flatten()
Chris@87 1390 if tmp.size == 0:
Chris@87 1391 return tmp
Chris@87 1392 tmp.sort()
Chris@87 1393 idx = concatenate(([True], tmp[1:] != tmp[:-1]))
Chris@87 1394 return tmp[idx]
Chris@87 1395 except AttributeError:
Chris@87 1396 items = sorted(set(x))
Chris@87 1397 return asarray(items)
Chris@87 1398
Chris@87 1399
Chris@87 1400 def extract(condition, arr):
Chris@87 1401 """
Chris@87 1402 Return the elements of an array that satisfy some condition.
Chris@87 1403
Chris@87 1404 This is equivalent to ``np.compress(ravel(condition), ravel(arr))``. If
Chris@87 1405 `condition` is boolean ``np.extract`` is equivalent to ``arr[condition]``.
Chris@87 1406
Chris@87 1407 Parameters
Chris@87 1408 ----------
Chris@87 1409 condition : array_like
Chris@87 1410 An array whose nonzero or True entries indicate the elements of `arr`
Chris@87 1411 to extract.
Chris@87 1412 arr : array_like
Chris@87 1413 Input array of the same size as `condition`.
Chris@87 1414
Chris@87 1415 Returns
Chris@87 1416 -------
Chris@87 1417 extract : ndarray
Chris@87 1418 Rank 1 array of values from `arr` where `condition` is True.
Chris@87 1419
Chris@87 1420 See Also
Chris@87 1421 --------
Chris@87 1422 take, put, copyto, compress
Chris@87 1423
Chris@87 1424 Examples
Chris@87 1425 --------
Chris@87 1426 >>> arr = np.arange(12).reshape((3, 4))
Chris@87 1427 >>> arr
Chris@87 1428 array([[ 0, 1, 2, 3],
Chris@87 1429 [ 4, 5, 6, 7],
Chris@87 1430 [ 8, 9, 10, 11]])
Chris@87 1431 >>> condition = np.mod(arr, 3)==0
Chris@87 1432 >>> condition
Chris@87 1433 array([[ True, False, False, True],
Chris@87 1434 [False, False, True, False],
Chris@87 1435 [False, True, False, False]], dtype=bool)
Chris@87 1436 >>> np.extract(condition, arr)
Chris@87 1437 array([0, 3, 6, 9])
Chris@87 1438
Chris@87 1439
Chris@87 1440 If `condition` is boolean:
Chris@87 1441
Chris@87 1442 >>> arr[condition]
Chris@87 1443 array([0, 3, 6, 9])
Chris@87 1444
Chris@87 1445 """
Chris@87 1446 return _nx.take(ravel(arr), nonzero(ravel(condition))[0])
Chris@87 1447
Chris@87 1448
Chris@87 1449 def place(arr, mask, vals):
Chris@87 1450 """
Chris@87 1451 Change elements of an array based on conditional and input values.
Chris@87 1452
Chris@87 1453 Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that
Chris@87 1454 `place` uses the first N elements of `vals`, where N is the number of
Chris@87 1455 True values in `mask`, while `copyto` uses the elements where `mask`
Chris@87 1456 is True.
Chris@87 1457
Chris@87 1458 Note that `extract` does the exact opposite of `place`.
Chris@87 1459
Chris@87 1460 Parameters
Chris@87 1461 ----------
Chris@87 1462 arr : array_like
Chris@87 1463 Array to put data into.
Chris@87 1464 mask : array_like
Chris@87 1465 Boolean mask array. Must have the same size as `a`.
Chris@87 1466 vals : 1-D sequence
Chris@87 1467 Values to put into `a`. Only the first N elements are used, where
Chris@87 1468 N is the number of True values in `mask`. If `vals` is smaller
Chris@87 1469 than N it will be repeated.
Chris@87 1470
Chris@87 1471 See Also
Chris@87 1472 --------
Chris@87 1473 copyto, put, take, extract
Chris@87 1474
Chris@87 1475 Examples
Chris@87 1476 --------
Chris@87 1477 >>> arr = np.arange(6).reshape(2, 3)
Chris@87 1478 >>> np.place(arr, arr>2, [44, 55])
Chris@87 1479 >>> arr
Chris@87 1480 array([[ 0, 1, 2],
Chris@87 1481 [44, 55, 44]])
Chris@87 1482
Chris@87 1483 """
Chris@87 1484 return _insert(arr, mask, vals)
Chris@87 1485
Chris@87 1486
Chris@87 1487 def disp(mesg, device=None, linefeed=True):
Chris@87 1488 """
Chris@87 1489 Display a message on a device.
Chris@87 1490
Chris@87 1491 Parameters
Chris@87 1492 ----------
Chris@87 1493 mesg : str
Chris@87 1494 Message to display.
Chris@87 1495 device : object
Chris@87 1496 Device to write message. If None, defaults to ``sys.stdout`` which is
Chris@87 1497 very similar to ``print``. `device` needs to have ``write()`` and
Chris@87 1498 ``flush()`` methods.
Chris@87 1499 linefeed : bool, optional
Chris@87 1500 Option whether to print a line feed or not. Defaults to True.
Chris@87 1501
Chris@87 1502 Raises
Chris@87 1503 ------
Chris@87 1504 AttributeError
Chris@87 1505 If `device` does not have a ``write()`` or ``flush()`` method.
Chris@87 1506
Chris@87 1507 Examples
Chris@87 1508 --------
Chris@87 1509 Besides ``sys.stdout``, a file-like object can also be used as it has
Chris@87 1510 both required methods:
Chris@87 1511
Chris@87 1512 >>> from StringIO import StringIO
Chris@87 1513 >>> buf = StringIO()
Chris@87 1514 >>> np.disp('"Display" in a file', device=buf)
Chris@87 1515 >>> buf.getvalue()
Chris@87 1516 '"Display" in a file\\n'
Chris@87 1517
Chris@87 1518 """
Chris@87 1519 if device is None:
Chris@87 1520 device = sys.stdout
Chris@87 1521 if linefeed:
Chris@87 1522 device.write('%s\n' % mesg)
Chris@87 1523 else:
Chris@87 1524 device.write('%s' % mesg)
Chris@87 1525 device.flush()
Chris@87 1526 return
Chris@87 1527
Chris@87 1528
Chris@87 1529 class vectorize(object):
Chris@87 1530 """
Chris@87 1531 vectorize(pyfunc, otypes='', doc=None, excluded=None, cache=False)
Chris@87 1532
Chris@87 1533 Generalized function class.
Chris@87 1534
Chris@87 1535 Define a vectorized function which takes a nested sequence
Chris@87 1536 of objects or numpy arrays as inputs and returns a
Chris@87 1537 numpy array as output. The vectorized function evaluates `pyfunc` over
Chris@87 1538 successive tuples of the input arrays like the python map function,
Chris@87 1539 except it uses the broadcasting rules of numpy.
Chris@87 1540
Chris@87 1541 The data type of the output of `vectorized` is determined by calling
Chris@87 1542 the function with the first element of the input. This can be avoided
Chris@87 1543 by specifying the `otypes` argument.
Chris@87 1544
Chris@87 1545 Parameters
Chris@87 1546 ----------
Chris@87 1547 pyfunc : callable
Chris@87 1548 A python function or method.
Chris@87 1549 otypes : str or list of dtypes, optional
Chris@87 1550 The output data type. It must be specified as either a string of
Chris@87 1551 typecode characters or a list of data type specifiers. There should
Chris@87 1552 be one data type specifier for each output.
Chris@87 1553 doc : str, optional
Chris@87 1554 The docstring for the function. If `None`, the docstring will be the
Chris@87 1555 ``pyfunc.__doc__``.
Chris@87 1556 excluded : set, optional
Chris@87 1557 Set of strings or integers representing the positional or keyword
Chris@87 1558 arguments for which the function will not be vectorized. These will be
Chris@87 1559 passed directly to `pyfunc` unmodified.
Chris@87 1560
Chris@87 1561 .. versionadded:: 1.7.0
Chris@87 1562
Chris@87 1563 cache : bool, optional
Chris@87 1564 If `True`, then cache the first function call that determines the number
Chris@87 1565 of outputs if `otypes` is not provided.
Chris@87 1566
Chris@87 1567 .. versionadded:: 1.7.0
Chris@87 1568
Chris@87 1569 Returns
Chris@87 1570 -------
Chris@87 1571 vectorized : callable
Chris@87 1572 Vectorized function.
Chris@87 1573
Chris@87 1574 Examples
Chris@87 1575 --------
Chris@87 1576 >>> def myfunc(a, b):
Chris@87 1577 ... "Return a-b if a>b, otherwise return a+b"
Chris@87 1578 ... if a > b:
Chris@87 1579 ... return a - b
Chris@87 1580 ... else:
Chris@87 1581 ... return a + b
Chris@87 1582
Chris@87 1583 >>> vfunc = np.vectorize(myfunc)
Chris@87 1584 >>> vfunc([1, 2, 3, 4], 2)
Chris@87 1585 array([3, 4, 1, 2])
Chris@87 1586
Chris@87 1587 The docstring is taken from the input function to `vectorize` unless it
Chris@87 1588 is specified
Chris@87 1589
Chris@87 1590 >>> vfunc.__doc__
Chris@87 1591 'Return a-b if a>b, otherwise return a+b'
Chris@87 1592 >>> vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`')
Chris@87 1593 >>> vfunc.__doc__
Chris@87 1594 'Vectorized `myfunc`'
Chris@87 1595
Chris@87 1596 The output type is determined by evaluating the first element of the input,
Chris@87 1597 unless it is specified
Chris@87 1598
Chris@87 1599 >>> out = vfunc([1, 2, 3, 4], 2)
Chris@87 1600 >>> type(out[0])
Chris@87 1601 <type 'numpy.int32'>
Chris@87 1602 >>> vfunc = np.vectorize(myfunc, otypes=[np.float])
Chris@87 1603 >>> out = vfunc([1, 2, 3, 4], 2)
Chris@87 1604 >>> type(out[0])
Chris@87 1605 <type 'numpy.float64'>
Chris@87 1606
Chris@87 1607 The `excluded` argument can be used to prevent vectorizing over certain
Chris@87 1608 arguments. This can be useful for array-like arguments of a fixed length
Chris@87 1609 such as the coefficients for a polynomial as in `polyval`:
Chris@87 1610
Chris@87 1611 >>> def mypolyval(p, x):
Chris@87 1612 ... _p = list(p)
Chris@87 1613 ... res = _p.pop(0)
Chris@87 1614 ... while _p:
Chris@87 1615 ... res = res*x + _p.pop(0)
Chris@87 1616 ... return res
Chris@87 1617 >>> vpolyval = np.vectorize(mypolyval, excluded=['p'])
Chris@87 1618 >>> vpolyval(p=[1, 2, 3], x=[0, 1])
Chris@87 1619 array([3, 6])
Chris@87 1620
Chris@87 1621 Positional arguments may also be excluded by specifying their position:
Chris@87 1622
Chris@87 1623 >>> vpolyval.excluded.add(0)
Chris@87 1624 >>> vpolyval([1, 2, 3], x=[0, 1])
Chris@87 1625 array([3, 6])
Chris@87 1626
Chris@87 1627 Notes
Chris@87 1628 -----
Chris@87 1629 The `vectorize` function is provided primarily for convenience, not for
Chris@87 1630 performance. The implementation is essentially a for loop.
Chris@87 1631
Chris@87 1632 If `otypes` is not specified, then a call to the function with the
Chris@87 1633 first argument will be used to determine the number of outputs. The
Chris@87 1634 results of this call will be cached if `cache` is `True` to prevent
Chris@87 1635 calling the function twice. However, to implement the cache, the
Chris@87 1636 original function must be wrapped which will slow down subsequent
Chris@87 1637 calls, so only do this if your function is expensive.
Chris@87 1638
Chris@87 1639 The new keyword argument interface and `excluded` argument support
Chris@87 1640 further degrades performance.
Chris@87 1641
Chris@87 1642 """
Chris@87 1643
Chris@87 1644 def __init__(self, pyfunc, otypes='', doc=None, excluded=None,
Chris@87 1645 cache=False):
Chris@87 1646 self.pyfunc = pyfunc
Chris@87 1647 self.cache = cache
Chris@87 1648 self._ufunc = None # Caching to improve default performance
Chris@87 1649
Chris@87 1650 if doc is None:
Chris@87 1651 self.__doc__ = pyfunc.__doc__
Chris@87 1652 else:
Chris@87 1653 self.__doc__ = doc
Chris@87 1654
Chris@87 1655 if isinstance(otypes, str):
Chris@87 1656 self.otypes = otypes
Chris@87 1657 for char in self.otypes:
Chris@87 1658 if char not in typecodes['All']:
Chris@87 1659 raise ValueError(
Chris@87 1660 "Invalid otype specified: %s" % (char,))
Chris@87 1661 elif iterable(otypes):
Chris@87 1662 self.otypes = ''.join([_nx.dtype(x).char for x in otypes])
Chris@87 1663 else:
Chris@87 1664 raise ValueError(
Chris@87 1665 "Invalid otype specification")
Chris@87 1666
Chris@87 1667 # Excluded variable support
Chris@87 1668 if excluded is None:
Chris@87 1669 excluded = set()
Chris@87 1670 self.excluded = set(excluded)
Chris@87 1671
Chris@87 1672 def __call__(self, *args, **kwargs):
Chris@87 1673 """
Chris@87 1674 Return arrays with the results of `pyfunc` broadcast (vectorized) over
Chris@87 1675 `args` and `kwargs` not in `excluded`.
Chris@87 1676 """
Chris@87 1677 excluded = self.excluded
Chris@87 1678 if not kwargs and not excluded:
Chris@87 1679 func = self.pyfunc
Chris@87 1680 vargs = args
Chris@87 1681 else:
Chris@87 1682 # The wrapper accepts only positional arguments: we use `names` and
Chris@87 1683 # `inds` to mutate `the_args` and `kwargs` to pass to the original
Chris@87 1684 # function.
Chris@87 1685 nargs = len(args)
Chris@87 1686
Chris@87 1687 names = [_n for _n in kwargs if _n not in excluded]
Chris@87 1688 inds = [_i for _i in range(nargs) if _i not in excluded]
Chris@87 1689 the_args = list(args)
Chris@87 1690
Chris@87 1691 def func(*vargs):
Chris@87 1692 for _n, _i in enumerate(inds):
Chris@87 1693 the_args[_i] = vargs[_n]
Chris@87 1694 kwargs.update(zip(names, vargs[len(inds):]))
Chris@87 1695 return self.pyfunc(*the_args, **kwargs)
Chris@87 1696
Chris@87 1697 vargs = [args[_i] for _i in inds]
Chris@87 1698 vargs.extend([kwargs[_n] for _n in names])
Chris@87 1699
Chris@87 1700 return self._vectorize_call(func=func, args=vargs)
Chris@87 1701
Chris@87 1702 def _get_ufunc_and_otypes(self, func, args):
Chris@87 1703 """Return (ufunc, otypes)."""
Chris@87 1704 # frompyfunc will fail if args is empty
Chris@87 1705 if not args:
Chris@87 1706 raise ValueError('args can not be empty')
Chris@87 1707
Chris@87 1708 if self.otypes:
Chris@87 1709 otypes = self.otypes
Chris@87 1710 nout = len(otypes)
Chris@87 1711
Chris@87 1712 # Note logic here: We only *use* self._ufunc if func is self.pyfunc
Chris@87 1713 # even though we set self._ufunc regardless.
Chris@87 1714 if func is self.pyfunc and self._ufunc is not None:
Chris@87 1715 ufunc = self._ufunc
Chris@87 1716 else:
Chris@87 1717 ufunc = self._ufunc = frompyfunc(func, len(args), nout)
Chris@87 1718 else:
Chris@87 1719 # Get number of outputs and output types by calling the function on
Chris@87 1720 # the first entries of args. We also cache the result to prevent
Chris@87 1721 # the subsequent call when the ufunc is evaluated.
Chris@87 1722 # Assumes that ufunc first evaluates the 0th elements in the input
Chris@87 1723 # arrays (the input values are not checked to ensure this)
Chris@87 1724 inputs = [asarray(_a).flat[0] for _a in args]
Chris@87 1725 outputs = func(*inputs)
Chris@87 1726
Chris@87 1727 # Performance note: profiling indicates that -- for simple
Chris@87 1728 # functions at least -- this wrapping can almost double the
Chris@87 1729 # execution time.
Chris@87 1730 # Hence we make it optional.
Chris@87 1731 if self.cache:
Chris@87 1732 _cache = [outputs]
Chris@87 1733
Chris@87 1734 def _func(*vargs):
Chris@87 1735 if _cache:
Chris@87 1736 return _cache.pop()
Chris@87 1737 else:
Chris@87 1738 return func(*vargs)
Chris@87 1739 else:
Chris@87 1740 _func = func
Chris@87 1741
Chris@87 1742 if isinstance(outputs, tuple):
Chris@87 1743 nout = len(outputs)
Chris@87 1744 else:
Chris@87 1745 nout = 1
Chris@87 1746 outputs = (outputs,)
Chris@87 1747
Chris@87 1748 otypes = ''.join([asarray(outputs[_k]).dtype.char
Chris@87 1749 for _k in range(nout)])
Chris@87 1750
Chris@87 1751 # Performance note: profiling indicates that creating the ufunc is
Chris@87 1752 # not a significant cost compared with wrapping so it seems not
Chris@87 1753 # worth trying to cache this.
Chris@87 1754 ufunc = frompyfunc(_func, len(args), nout)
Chris@87 1755
Chris@87 1756 return ufunc, otypes
Chris@87 1757
Chris@87 1758 def _vectorize_call(self, func, args):
Chris@87 1759 """Vectorized call to `func` over positional `args`."""
Chris@87 1760 if not args:
Chris@87 1761 _res = func()
Chris@87 1762 else:
Chris@87 1763 ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
Chris@87 1764
Chris@87 1765 # Convert args to object arrays first
Chris@87 1766 inputs = [array(_a, copy=False, subok=True, dtype=object)
Chris@87 1767 for _a in args]
Chris@87 1768
Chris@87 1769 outputs = ufunc(*inputs)
Chris@87 1770
Chris@87 1771 if ufunc.nout == 1:
Chris@87 1772 _res = array(outputs,
Chris@87 1773 copy=False, subok=True, dtype=otypes[0])
Chris@87 1774 else:
Chris@87 1775 _res = tuple([array(_x, copy=False, subok=True, dtype=_t)
Chris@87 1776 for _x, _t in zip(outputs, otypes)])
Chris@87 1777 return _res
Chris@87 1778
Chris@87 1779
Chris@87 1780 def cov(m, y=None, rowvar=1, bias=0, ddof=None):
Chris@87 1781 """
Chris@87 1782 Estimate a covariance matrix, given data.
Chris@87 1783
Chris@87 1784 Covariance indicates the level to which two variables vary together.
Chris@87 1785 If we examine N-dimensional samples, :math:`X = [x_1, x_2, ... x_N]^T`,
Chris@87 1786 then the covariance matrix element :math:`C_{ij}` is the covariance of
Chris@87 1787 :math:`x_i` and :math:`x_j`. The element :math:`C_{ii}` is the variance
Chris@87 1788 of :math:`x_i`.
Chris@87 1789
Chris@87 1790 Parameters
Chris@87 1791 ----------
Chris@87 1792 m : array_like
Chris@87 1793 A 1-D or 2-D array containing multiple variables and observations.
Chris@87 1794 Each row of `m` represents a variable, and each column a single
Chris@87 1795 observation of all those variables. Also see `rowvar` below.
Chris@87 1796 y : array_like, optional
Chris@87 1797 An additional set of variables and observations. `y` has the same
Chris@87 1798 form as that of `m`.
Chris@87 1799 rowvar : int, optional
Chris@87 1800 If `rowvar` is non-zero (default), then each row represents a
Chris@87 1801 variable, with observations in the columns. Otherwise, the relationship
Chris@87 1802 is transposed: each column represents a variable, while the rows
Chris@87 1803 contain observations.
Chris@87 1804 bias : int, optional
Chris@87 1805 Default normalization is by ``(N - 1)``, where ``N`` is the number of
Chris@87 1806 observations given (unbiased estimate). If `bias` is 1, then
Chris@87 1807 normalization is by ``N``. These values can be overridden by using
Chris@87 1808 the keyword ``ddof`` in numpy versions >= 1.5.
Chris@87 1809 ddof : int, optional
Chris@87 1810 .. versionadded:: 1.5
Chris@87 1811 If not ``None`` normalization is by ``(N - ddof)``, where ``N`` is
Chris@87 1812 the number of observations; this overrides the value implied by
Chris@87 1813 ``bias``. The default value is ``None``.
Chris@87 1814
Chris@87 1815 Returns
Chris@87 1816 -------
Chris@87 1817 out : ndarray
Chris@87 1818 The covariance matrix of the variables.
Chris@87 1819
Chris@87 1820 See Also
Chris@87 1821 --------
Chris@87 1822 corrcoef : Normalized covariance matrix
Chris@87 1823
Chris@87 1824 Examples
Chris@87 1825 --------
Chris@87 1826 Consider two variables, :math:`x_0` and :math:`x_1`, which
Chris@87 1827 correlate perfectly, but in opposite directions:
Chris@87 1828
Chris@87 1829 >>> x = np.array([[0, 2], [1, 1], [2, 0]]).T
Chris@87 1830 >>> x
Chris@87 1831 array([[0, 1, 2],
Chris@87 1832 [2, 1, 0]])
Chris@87 1833
Chris@87 1834 Note how :math:`x_0` increases while :math:`x_1` decreases. The covariance
Chris@87 1835 matrix shows this clearly:
Chris@87 1836
Chris@87 1837 >>> np.cov(x)
Chris@87 1838 array([[ 1., -1.],
Chris@87 1839 [-1., 1.]])
Chris@87 1840
Chris@87 1841 Note that element :math:`C_{0,1}`, which shows the correlation between
Chris@87 1842 :math:`x_0` and :math:`x_1`, is negative.
Chris@87 1843
Chris@87 1844 Further, note how `x` and `y` are combined:
Chris@87 1845
Chris@87 1846 >>> x = [-2.1, -1, 4.3]
Chris@87 1847 >>> y = [3, 1.1, 0.12]
Chris@87 1848 >>> X = np.vstack((x,y))
Chris@87 1849 >>> print np.cov(X)
Chris@87 1850 [[ 11.71 -4.286 ]
Chris@87 1851 [ -4.286 2.14413333]]
Chris@87 1852 >>> print np.cov(x, y)
Chris@87 1853 [[ 11.71 -4.286 ]
Chris@87 1854 [ -4.286 2.14413333]]
Chris@87 1855 >>> print np.cov(x)
Chris@87 1856 11.71
Chris@87 1857
Chris@87 1858 """
Chris@87 1859 # Check inputs
Chris@87 1860 if ddof is not None and ddof != int(ddof):
Chris@87 1861 raise ValueError(
Chris@87 1862 "ddof must be integer")
Chris@87 1863
Chris@87 1864 # Handles complex arrays too
Chris@87 1865 m = np.asarray(m)
Chris@87 1866 if y is None:
Chris@87 1867 dtype = np.result_type(m, np.float64)
Chris@87 1868 else:
Chris@87 1869 y = np.asarray(y)
Chris@87 1870 dtype = np.result_type(m, y, np.float64)
Chris@87 1871 X = array(m, ndmin=2, dtype=dtype)
Chris@87 1872
Chris@87 1873 if X.shape[0] == 1:
Chris@87 1874 rowvar = 1
Chris@87 1875 if rowvar:
Chris@87 1876 N = X.shape[1]
Chris@87 1877 axis = 0
Chris@87 1878 else:
Chris@87 1879 N = X.shape[0]
Chris@87 1880 axis = 1
Chris@87 1881
Chris@87 1882 # check ddof
Chris@87 1883 if ddof is None:
Chris@87 1884 if bias == 0:
Chris@87 1885 ddof = 1
Chris@87 1886 else:
Chris@87 1887 ddof = 0
Chris@87 1888 fact = float(N - ddof)
Chris@87 1889 if fact <= 0:
Chris@87 1890 warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
Chris@87 1891 fact = 0.0
Chris@87 1892
Chris@87 1893 if y is not None:
Chris@87 1894 y = array(y, copy=False, ndmin=2, dtype=dtype)
Chris@87 1895 X = concatenate((X, y), axis)
Chris@87 1896
Chris@87 1897 X -= X.mean(axis=1-axis, keepdims=True)
Chris@87 1898 if not rowvar:
Chris@87 1899 return (dot(X.T, X.conj()) / fact).squeeze()
Chris@87 1900 else:
Chris@87 1901 return (dot(X, X.T.conj()) / fact).squeeze()
Chris@87 1902
Chris@87 1903
Chris@87 1904 def corrcoef(x, y=None, rowvar=1, bias=0, ddof=None):
Chris@87 1905 """
Chris@87 1906 Return correlation coefficients.
Chris@87 1907
Chris@87 1908 Please refer to the documentation for `cov` for more detail. The
Chris@87 1909 relationship between the correlation coefficient matrix, `P`, and the
Chris@87 1910 covariance matrix, `C`, is
Chris@87 1911
Chris@87 1912 .. math:: P_{ij} = \\frac{ C_{ij} } { \\sqrt{ C_{ii} * C_{jj} } }
Chris@87 1913
Chris@87 1914 The values of `P` are between -1 and 1, inclusive.
Chris@87 1915
Chris@87 1916 Parameters
Chris@87 1917 ----------
Chris@87 1918 x : array_like
Chris@87 1919 A 1-D or 2-D array containing multiple variables and observations.
Chris@87 1920 Each row of `m` represents a variable, and each column a single
Chris@87 1921 observation of all those variables. Also see `rowvar` below.
Chris@87 1922 y : array_like, optional
Chris@87 1923 An additional set of variables and observations. `y` has the same
Chris@87 1924 shape as `m`.
Chris@87 1925 rowvar : int, optional
Chris@87 1926 If `rowvar` is non-zero (default), then each row represents a
Chris@87 1927 variable, with observations in the columns. Otherwise, the relationship
Chris@87 1928 is transposed: each column represents a variable, while the rows
Chris@87 1929 contain observations.
Chris@87 1930 bias : int, optional
Chris@87 1931 Default normalization is by ``(N - 1)``, where ``N`` is the number of
Chris@87 1932 observations (unbiased estimate). If `bias` is 1, then
Chris@87 1933 normalization is by ``N``. These values can be overridden by using
Chris@87 1934 the keyword ``ddof`` in numpy versions >= 1.5.
Chris@87 1935 ddof : {None, int}, optional
Chris@87 1936 .. versionadded:: 1.5
Chris@87 1937 If not ``None`` normalization is by ``(N - ddof)``, where ``N`` is
Chris@87 1938 the number of observations; this overrides the value implied by
Chris@87 1939 ``bias``. The default value is ``None``.
Chris@87 1940
Chris@87 1941 Returns
Chris@87 1942 -------
Chris@87 1943 out : ndarray
Chris@87 1944 The correlation coefficient matrix of the variables.
Chris@87 1945
Chris@87 1946 See Also
Chris@87 1947 --------
Chris@87 1948 cov : Covariance matrix
Chris@87 1949
Chris@87 1950 """
Chris@87 1951 c = cov(x, y, rowvar, bias, ddof)
Chris@87 1952 try:
Chris@87 1953 d = diag(c)
Chris@87 1954 except ValueError: # scalar covariance
Chris@87 1955 # nan if incorrect value (nan, inf, 0), 1 otherwise
Chris@87 1956 return c / c
Chris@87 1957 return c / sqrt(multiply.outer(d, d))
Chris@87 1958
Chris@87 1959
Chris@87 1960 def blackman(M):
Chris@87 1961 """
Chris@87 1962 Return the Blackman window.
Chris@87 1963
Chris@87 1964 The Blackman window is a taper formed by using the first three
Chris@87 1965 terms of a summation of cosines. It was designed to have close to the
Chris@87 1966 minimal leakage possible. It is close to optimal, only slightly worse
Chris@87 1967 than a Kaiser window.
Chris@87 1968
Chris@87 1969 Parameters
Chris@87 1970 ----------
Chris@87 1971 M : int
Chris@87 1972 Number of points in the output window. If zero or less, an empty
Chris@87 1973 array is returned.
Chris@87 1974
Chris@87 1975 Returns
Chris@87 1976 -------
Chris@87 1977 out : ndarray
Chris@87 1978 The window, with the maximum value normalized to one (the value one
Chris@87 1979 appears only if the number of samples is odd).
Chris@87 1980
Chris@87 1981 See Also
Chris@87 1982 --------
Chris@87 1983 bartlett, hamming, hanning, kaiser
Chris@87 1984
Chris@87 1985 Notes
Chris@87 1986 -----
Chris@87 1987 The Blackman window is defined as
Chris@87 1988
Chris@87 1989 .. math:: w(n) = 0.42 - 0.5 \\cos(2\\pi n/M) + 0.08 \\cos(4\\pi n/M)
Chris@87 1990
Chris@87 1991 Most references to the Blackman window come from the signal processing
Chris@87 1992 literature, where it is used as one of many windowing functions for
Chris@87 1993 smoothing values. It is also known as an apodization (which means
Chris@87 1994 "removing the foot", i.e. smoothing discontinuities at the beginning
Chris@87 1995 and end of the sampled signal) or tapering function. It is known as a
Chris@87 1996 "near optimal" tapering function, almost as good (by some measures)
Chris@87 1997 as the kaiser window.
Chris@87 1998
Chris@87 1999 References
Chris@87 2000 ----------
Chris@87 2001 Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra,
Chris@87 2002 Dover Publications, New York.
Chris@87 2003
Chris@87 2004 Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing.
Chris@87 2005 Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471.
Chris@87 2006
Chris@87 2007 Examples
Chris@87 2008 --------
Chris@87 2009 >>> np.blackman(12)
Chris@87 2010 array([ -1.38777878e-17, 3.26064346e-02, 1.59903635e-01,
Chris@87 2011 4.14397981e-01, 7.36045180e-01, 9.67046769e-01,
Chris@87 2012 9.67046769e-01, 7.36045180e-01, 4.14397981e-01,
Chris@87 2013 1.59903635e-01, 3.26064346e-02, -1.38777878e-17])
Chris@87 2014
Chris@87 2015
Chris@87 2016 Plot the window and the frequency response:
Chris@87 2017
Chris@87 2018 >>> from numpy.fft import fft, fftshift
Chris@87 2019 >>> window = np.blackman(51)
Chris@87 2020 >>> plt.plot(window)
Chris@87 2021 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2022 >>> plt.title("Blackman window")
Chris@87 2023 <matplotlib.text.Text object at 0x...>
Chris@87 2024 >>> plt.ylabel("Amplitude")
Chris@87 2025 <matplotlib.text.Text object at 0x...>
Chris@87 2026 >>> plt.xlabel("Sample")
Chris@87 2027 <matplotlib.text.Text object at 0x...>
Chris@87 2028 >>> plt.show()
Chris@87 2029
Chris@87 2030 >>> plt.figure()
Chris@87 2031 <matplotlib.figure.Figure object at 0x...>
Chris@87 2032 >>> A = fft(window, 2048) / 25.5
Chris@87 2033 >>> mag = np.abs(fftshift(A))
Chris@87 2034 >>> freq = np.linspace(-0.5, 0.5, len(A))
Chris@87 2035 >>> response = 20 * np.log10(mag)
Chris@87 2036 >>> response = np.clip(response, -100, 100)
Chris@87 2037 >>> plt.plot(freq, response)
Chris@87 2038 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2039 >>> plt.title("Frequency response of Blackman window")
Chris@87 2040 <matplotlib.text.Text object at 0x...>
Chris@87 2041 >>> plt.ylabel("Magnitude [dB]")
Chris@87 2042 <matplotlib.text.Text object at 0x...>
Chris@87 2043 >>> plt.xlabel("Normalized frequency [cycles per sample]")
Chris@87 2044 <matplotlib.text.Text object at 0x...>
Chris@87 2045 >>> plt.axis('tight')
Chris@87 2046 (-0.5, 0.5, -100.0, ...)
Chris@87 2047 >>> plt.show()
Chris@87 2048
Chris@87 2049 """
Chris@87 2050 if M < 1:
Chris@87 2051 return array([])
Chris@87 2052 if M == 1:
Chris@87 2053 return ones(1, float)
Chris@87 2054 n = arange(0, M)
Chris@87 2055 return 0.42 - 0.5*cos(2.0*pi*n/(M-1)) + 0.08*cos(4.0*pi*n/(M-1))
Chris@87 2056
Chris@87 2057
Chris@87 2058 def bartlett(M):
Chris@87 2059 """
Chris@87 2060 Return the Bartlett window.
Chris@87 2061
Chris@87 2062 The Bartlett window is very similar to a triangular window, except
Chris@87 2063 that the end points are at zero. It is often used in signal
Chris@87 2064 processing for tapering a signal, without generating too much
Chris@87 2065 ripple in the frequency domain.
Chris@87 2066
Chris@87 2067 Parameters
Chris@87 2068 ----------
Chris@87 2069 M : int
Chris@87 2070 Number of points in the output window. If zero or less, an
Chris@87 2071 empty array is returned.
Chris@87 2072
Chris@87 2073 Returns
Chris@87 2074 -------
Chris@87 2075 out : array
Chris@87 2076 The triangular window, with the maximum value normalized to one
Chris@87 2077 (the value one appears only if the number of samples is odd), with
Chris@87 2078 the first and last samples equal to zero.
Chris@87 2079
Chris@87 2080 See Also
Chris@87 2081 --------
Chris@87 2082 blackman, hamming, hanning, kaiser
Chris@87 2083
Chris@87 2084 Notes
Chris@87 2085 -----
Chris@87 2086 The Bartlett window is defined as
Chris@87 2087
Chris@87 2088 .. math:: w(n) = \\frac{2}{M-1} \\left(
Chris@87 2089 \\frac{M-1}{2} - \\left|n - \\frac{M-1}{2}\\right|
Chris@87 2090 \\right)
Chris@87 2091
Chris@87 2092 Most references to the Bartlett window come from the signal
Chris@87 2093 processing literature, where it is used as one of many windowing
Chris@87 2094 functions for smoothing values. Note that convolution with this
Chris@87 2095 window produces linear interpolation. It is also known as an
Chris@87 2096 apodization (which means"removing the foot", i.e. smoothing
Chris@87 2097 discontinuities at the beginning and end of the sampled signal) or
Chris@87 2098 tapering function. The fourier transform of the Bartlett is the product
Chris@87 2099 of two sinc functions.
Chris@87 2100 Note the excellent discussion in Kanasewich.
Chris@87 2101
Chris@87 2102 References
Chris@87 2103 ----------
Chris@87 2104 .. [1] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra",
Chris@87 2105 Biometrika 37, 1-16, 1950.
Chris@87 2106 .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
Chris@87 2107 The University of Alberta Press, 1975, pp. 109-110.
Chris@87 2108 .. [3] A.V. Oppenheim and R.W. Schafer, "Discrete-Time Signal
Chris@87 2109 Processing", Prentice-Hall, 1999, pp. 468-471.
Chris@87 2110 .. [4] Wikipedia, "Window function",
Chris@87 2111 http://en.wikipedia.org/wiki/Window_function
Chris@87 2112 .. [5] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
Chris@87 2113 "Numerical Recipes", Cambridge University Press, 1986, page 429.
Chris@87 2114
Chris@87 2115
Chris@87 2116 Examples
Chris@87 2117 --------
Chris@87 2118 >>> np.bartlett(12)
Chris@87 2119 array([ 0. , 0.18181818, 0.36363636, 0.54545455, 0.72727273,
Chris@87 2120 0.90909091, 0.90909091, 0.72727273, 0.54545455, 0.36363636,
Chris@87 2121 0.18181818, 0. ])
Chris@87 2122
Chris@87 2123 Plot the window and its frequency response (requires SciPy and matplotlib):
Chris@87 2124
Chris@87 2125 >>> from numpy.fft import fft, fftshift
Chris@87 2126 >>> window = np.bartlett(51)
Chris@87 2127 >>> plt.plot(window)
Chris@87 2128 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2129 >>> plt.title("Bartlett window")
Chris@87 2130 <matplotlib.text.Text object at 0x...>
Chris@87 2131 >>> plt.ylabel("Amplitude")
Chris@87 2132 <matplotlib.text.Text object at 0x...>
Chris@87 2133 >>> plt.xlabel("Sample")
Chris@87 2134 <matplotlib.text.Text object at 0x...>
Chris@87 2135 >>> plt.show()
Chris@87 2136
Chris@87 2137 >>> plt.figure()
Chris@87 2138 <matplotlib.figure.Figure object at 0x...>
Chris@87 2139 >>> A = fft(window, 2048) / 25.5
Chris@87 2140 >>> mag = np.abs(fftshift(A))
Chris@87 2141 >>> freq = np.linspace(-0.5, 0.5, len(A))
Chris@87 2142 >>> response = 20 * np.log10(mag)
Chris@87 2143 >>> response = np.clip(response, -100, 100)
Chris@87 2144 >>> plt.plot(freq, response)
Chris@87 2145 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2146 >>> plt.title("Frequency response of Bartlett window")
Chris@87 2147 <matplotlib.text.Text object at 0x...>
Chris@87 2148 >>> plt.ylabel("Magnitude [dB]")
Chris@87 2149 <matplotlib.text.Text object at 0x...>
Chris@87 2150 >>> plt.xlabel("Normalized frequency [cycles per sample]")
Chris@87 2151 <matplotlib.text.Text object at 0x...>
Chris@87 2152 >>> plt.axis('tight')
Chris@87 2153 (-0.5, 0.5, -100.0, ...)
Chris@87 2154 >>> plt.show()
Chris@87 2155
Chris@87 2156 """
Chris@87 2157 if M < 1:
Chris@87 2158 return array([])
Chris@87 2159 if M == 1:
Chris@87 2160 return ones(1, float)
Chris@87 2161 n = arange(0, M)
Chris@87 2162 return where(less_equal(n, (M-1)/2.0), 2.0*n/(M-1), 2.0 - 2.0*n/(M-1))
Chris@87 2163
Chris@87 2164
Chris@87 2165 def hanning(M):
Chris@87 2166 """
Chris@87 2167 Return the Hanning window.
Chris@87 2168
Chris@87 2169 The Hanning window is a taper formed by using a weighted cosine.
Chris@87 2170
Chris@87 2171 Parameters
Chris@87 2172 ----------
Chris@87 2173 M : int
Chris@87 2174 Number of points in the output window. If zero or less, an
Chris@87 2175 empty array is returned.
Chris@87 2176
Chris@87 2177 Returns
Chris@87 2178 -------
Chris@87 2179 out : ndarray, shape(M,)
Chris@87 2180 The window, with the maximum value normalized to one (the value
Chris@87 2181 one appears only if `M` is odd).
Chris@87 2182
Chris@87 2183 See Also
Chris@87 2184 --------
Chris@87 2185 bartlett, blackman, hamming, kaiser
Chris@87 2186
Chris@87 2187 Notes
Chris@87 2188 -----
Chris@87 2189 The Hanning window is defined as
Chris@87 2190
Chris@87 2191 .. math:: w(n) = 0.5 - 0.5cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
Chris@87 2192 \\qquad 0 \\leq n \\leq M-1
Chris@87 2193
Chris@87 2194 The Hanning was named for Julius van Hann, an Austrian meteorologist.
Chris@87 2195 It is also known as the Cosine Bell. Some authors prefer that it be
Chris@87 2196 called a Hann window, to help avoid confusion with the very similar
Chris@87 2197 Hamming window.
Chris@87 2198
Chris@87 2199 Most references to the Hanning window come from the signal processing
Chris@87 2200 literature, where it is used as one of many windowing functions for
Chris@87 2201 smoothing values. It is also known as an apodization (which means
Chris@87 2202 "removing the foot", i.e. smoothing discontinuities at the beginning
Chris@87 2203 and end of the sampled signal) or tapering function.
Chris@87 2204
Chris@87 2205 References
Chris@87 2206 ----------
Chris@87 2207 .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
Chris@87 2208 spectra, Dover Publications, New York.
Chris@87 2209 .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
Chris@87 2210 The University of Alberta Press, 1975, pp. 106-108.
Chris@87 2211 .. [3] Wikipedia, "Window function",
Chris@87 2212 http://en.wikipedia.org/wiki/Window_function
Chris@87 2213 .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
Chris@87 2214 "Numerical Recipes", Cambridge University Press, 1986, page 425.
Chris@87 2215
Chris@87 2216 Examples
Chris@87 2217 --------
Chris@87 2218 >>> np.hanning(12)
Chris@87 2219 array([ 0. , 0.07937323, 0.29229249, 0.57115742, 0.82743037,
Chris@87 2220 0.97974649, 0.97974649, 0.82743037, 0.57115742, 0.29229249,
Chris@87 2221 0.07937323, 0. ])
Chris@87 2222
Chris@87 2223 Plot the window and its frequency response:
Chris@87 2224
Chris@87 2225 >>> from numpy.fft import fft, fftshift
Chris@87 2226 >>> window = np.hanning(51)
Chris@87 2227 >>> plt.plot(window)
Chris@87 2228 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2229 >>> plt.title("Hann window")
Chris@87 2230 <matplotlib.text.Text object at 0x...>
Chris@87 2231 >>> plt.ylabel("Amplitude")
Chris@87 2232 <matplotlib.text.Text object at 0x...>
Chris@87 2233 >>> plt.xlabel("Sample")
Chris@87 2234 <matplotlib.text.Text object at 0x...>
Chris@87 2235 >>> plt.show()
Chris@87 2236
Chris@87 2237 >>> plt.figure()
Chris@87 2238 <matplotlib.figure.Figure object at 0x...>
Chris@87 2239 >>> A = fft(window, 2048) / 25.5
Chris@87 2240 >>> mag = np.abs(fftshift(A))
Chris@87 2241 >>> freq = np.linspace(-0.5, 0.5, len(A))
Chris@87 2242 >>> response = 20 * np.log10(mag)
Chris@87 2243 >>> response = np.clip(response, -100, 100)
Chris@87 2244 >>> plt.plot(freq, response)
Chris@87 2245 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2246 >>> plt.title("Frequency response of the Hann window")
Chris@87 2247 <matplotlib.text.Text object at 0x...>
Chris@87 2248 >>> plt.ylabel("Magnitude [dB]")
Chris@87 2249 <matplotlib.text.Text object at 0x...>
Chris@87 2250 >>> plt.xlabel("Normalized frequency [cycles per sample]")
Chris@87 2251 <matplotlib.text.Text object at 0x...>
Chris@87 2252 >>> plt.axis('tight')
Chris@87 2253 (-0.5, 0.5, -100.0, ...)
Chris@87 2254 >>> plt.show()
Chris@87 2255
Chris@87 2256 """
Chris@87 2257 if M < 1:
Chris@87 2258 return array([])
Chris@87 2259 if M == 1:
Chris@87 2260 return ones(1, float)
Chris@87 2261 n = arange(0, M)
Chris@87 2262 return 0.5 - 0.5*cos(2.0*pi*n/(M-1))
Chris@87 2263
Chris@87 2264
Chris@87 2265 def hamming(M):
Chris@87 2266 """
Chris@87 2267 Return the Hamming window.
Chris@87 2268
Chris@87 2269 The Hamming window is a taper formed by using a weighted cosine.
Chris@87 2270
Chris@87 2271 Parameters
Chris@87 2272 ----------
Chris@87 2273 M : int
Chris@87 2274 Number of points in the output window. If zero or less, an
Chris@87 2275 empty array is returned.
Chris@87 2276
Chris@87 2277 Returns
Chris@87 2278 -------
Chris@87 2279 out : ndarray
Chris@87 2280 The window, with the maximum value normalized to one (the value
Chris@87 2281 one appears only if the number of samples is odd).
Chris@87 2282
Chris@87 2283 See Also
Chris@87 2284 --------
Chris@87 2285 bartlett, blackman, hanning, kaiser
Chris@87 2286
Chris@87 2287 Notes
Chris@87 2288 -----
Chris@87 2289 The Hamming window is defined as
Chris@87 2290
Chris@87 2291 .. math:: w(n) = 0.54 - 0.46cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
Chris@87 2292 \\qquad 0 \\leq n \\leq M-1
Chris@87 2293
Chris@87 2294 The Hamming was named for R. W. Hamming, an associate of J. W. Tukey
Chris@87 2295 and is described in Blackman and Tukey. It was recommended for
Chris@87 2296 smoothing the truncated autocovariance function in the time domain.
Chris@87 2297 Most references to the Hamming window come from the signal processing
Chris@87 2298 literature, where it is used as one of many windowing functions for
Chris@87 2299 smoothing values. It is also known as an apodization (which means
Chris@87 2300 "removing the foot", i.e. smoothing discontinuities at the beginning
Chris@87 2301 and end of the sampled signal) or tapering function.
Chris@87 2302
Chris@87 2303 References
Chris@87 2304 ----------
Chris@87 2305 .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
Chris@87 2306 spectra, Dover Publications, New York.
Chris@87 2307 .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
Chris@87 2308 University of Alberta Press, 1975, pp. 109-110.
Chris@87 2309 .. [3] Wikipedia, "Window function",
Chris@87 2310 http://en.wikipedia.org/wiki/Window_function
Chris@87 2311 .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
Chris@87 2312 "Numerical Recipes", Cambridge University Press, 1986, page 425.
Chris@87 2313
Chris@87 2314 Examples
Chris@87 2315 --------
Chris@87 2316 >>> np.hamming(12)
Chris@87 2317 array([ 0.08 , 0.15302337, 0.34890909, 0.60546483, 0.84123594,
Chris@87 2318 0.98136677, 0.98136677, 0.84123594, 0.60546483, 0.34890909,
Chris@87 2319 0.15302337, 0.08 ])
Chris@87 2320
Chris@87 2321 Plot the window and the frequency response:
Chris@87 2322
Chris@87 2323 >>> from numpy.fft import fft, fftshift
Chris@87 2324 >>> window = np.hamming(51)
Chris@87 2325 >>> plt.plot(window)
Chris@87 2326 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2327 >>> plt.title("Hamming window")
Chris@87 2328 <matplotlib.text.Text object at 0x...>
Chris@87 2329 >>> plt.ylabel("Amplitude")
Chris@87 2330 <matplotlib.text.Text object at 0x...>
Chris@87 2331 >>> plt.xlabel("Sample")
Chris@87 2332 <matplotlib.text.Text object at 0x...>
Chris@87 2333 >>> plt.show()
Chris@87 2334
Chris@87 2335 >>> plt.figure()
Chris@87 2336 <matplotlib.figure.Figure object at 0x...>
Chris@87 2337 >>> A = fft(window, 2048) / 25.5
Chris@87 2338 >>> mag = np.abs(fftshift(A))
Chris@87 2339 >>> freq = np.linspace(-0.5, 0.5, len(A))
Chris@87 2340 >>> response = 20 * np.log10(mag)
Chris@87 2341 >>> response = np.clip(response, -100, 100)
Chris@87 2342 >>> plt.plot(freq, response)
Chris@87 2343 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2344 >>> plt.title("Frequency response of Hamming window")
Chris@87 2345 <matplotlib.text.Text object at 0x...>
Chris@87 2346 >>> plt.ylabel("Magnitude [dB]")
Chris@87 2347 <matplotlib.text.Text object at 0x...>
Chris@87 2348 >>> plt.xlabel("Normalized frequency [cycles per sample]")
Chris@87 2349 <matplotlib.text.Text object at 0x...>
Chris@87 2350 >>> plt.axis('tight')
Chris@87 2351 (-0.5, 0.5, -100.0, ...)
Chris@87 2352 >>> plt.show()
Chris@87 2353
Chris@87 2354 """
Chris@87 2355 if M < 1:
Chris@87 2356 return array([])
Chris@87 2357 if M == 1:
Chris@87 2358 return ones(1, float)
Chris@87 2359 n = arange(0, M)
Chris@87 2360 return 0.54 - 0.46*cos(2.0*pi*n/(M-1))
Chris@87 2361
Chris@87 2362 ## Code from cephes for i0
Chris@87 2363
Chris@87 2364 _i0A = [
Chris@87 2365 -4.41534164647933937950E-18,
Chris@87 2366 3.33079451882223809783E-17,
Chris@87 2367 -2.43127984654795469359E-16,
Chris@87 2368 1.71539128555513303061E-15,
Chris@87 2369 -1.16853328779934516808E-14,
Chris@87 2370 7.67618549860493561688E-14,
Chris@87 2371 -4.85644678311192946090E-13,
Chris@87 2372 2.95505266312963983461E-12,
Chris@87 2373 -1.72682629144155570723E-11,
Chris@87 2374 9.67580903537323691224E-11,
Chris@87 2375 -5.18979560163526290666E-10,
Chris@87 2376 2.65982372468238665035E-9,
Chris@87 2377 -1.30002500998624804212E-8,
Chris@87 2378 6.04699502254191894932E-8,
Chris@87 2379 -2.67079385394061173391E-7,
Chris@87 2380 1.11738753912010371815E-6,
Chris@87 2381 -4.41673835845875056359E-6,
Chris@87 2382 1.64484480707288970893E-5,
Chris@87 2383 -5.75419501008210370398E-5,
Chris@87 2384 1.88502885095841655729E-4,
Chris@87 2385 -5.76375574538582365885E-4,
Chris@87 2386 1.63947561694133579842E-3,
Chris@87 2387 -4.32430999505057594430E-3,
Chris@87 2388 1.05464603945949983183E-2,
Chris@87 2389 -2.37374148058994688156E-2,
Chris@87 2390 4.93052842396707084878E-2,
Chris@87 2391 -9.49010970480476444210E-2,
Chris@87 2392 1.71620901522208775349E-1,
Chris@87 2393 -3.04682672343198398683E-1,
Chris@87 2394 6.76795274409476084995E-1
Chris@87 2395 ]
Chris@87 2396
Chris@87 2397 _i0B = [
Chris@87 2398 -7.23318048787475395456E-18,
Chris@87 2399 -4.83050448594418207126E-18,
Chris@87 2400 4.46562142029675999901E-17,
Chris@87 2401 3.46122286769746109310E-17,
Chris@87 2402 -2.82762398051658348494E-16,
Chris@87 2403 -3.42548561967721913462E-16,
Chris@87 2404 1.77256013305652638360E-15,
Chris@87 2405 3.81168066935262242075E-15,
Chris@87 2406 -9.55484669882830764870E-15,
Chris@87 2407 -4.15056934728722208663E-14,
Chris@87 2408 1.54008621752140982691E-14,
Chris@87 2409 3.85277838274214270114E-13,
Chris@87 2410 7.18012445138366623367E-13,
Chris@87 2411 -1.79417853150680611778E-12,
Chris@87 2412 -1.32158118404477131188E-11,
Chris@87 2413 -3.14991652796324136454E-11,
Chris@87 2414 1.18891471078464383424E-11,
Chris@87 2415 4.94060238822496958910E-10,
Chris@87 2416 3.39623202570838634515E-9,
Chris@87 2417 2.26666899049817806459E-8,
Chris@87 2418 2.04891858946906374183E-7,
Chris@87 2419 2.89137052083475648297E-6,
Chris@87 2420 6.88975834691682398426E-5,
Chris@87 2421 3.36911647825569408990E-3,
Chris@87 2422 8.04490411014108831608E-1
Chris@87 2423 ]
Chris@87 2424
Chris@87 2425
Chris@87 2426 def _chbevl(x, vals):
Chris@87 2427 b0 = vals[0]
Chris@87 2428 b1 = 0.0
Chris@87 2429
Chris@87 2430 for i in range(1, len(vals)):
Chris@87 2431 b2 = b1
Chris@87 2432 b1 = b0
Chris@87 2433 b0 = x*b1 - b2 + vals[i]
Chris@87 2434
Chris@87 2435 return 0.5*(b0 - b2)
Chris@87 2436
Chris@87 2437
Chris@87 2438 def _i0_1(x):
Chris@87 2439 return exp(x) * _chbevl(x/2.0-2, _i0A)
Chris@87 2440
Chris@87 2441
Chris@87 2442 def _i0_2(x):
Chris@87 2443 return exp(x) * _chbevl(32.0/x - 2.0, _i0B) / sqrt(x)
Chris@87 2444
Chris@87 2445
Chris@87 2446 def i0(x):
Chris@87 2447 """
Chris@87 2448 Modified Bessel function of the first kind, order 0.
Chris@87 2449
Chris@87 2450 Usually denoted :math:`I_0`. This function does broadcast, but will *not*
Chris@87 2451 "up-cast" int dtype arguments unless accompanied by at least one float or
Chris@87 2452 complex dtype argument (see Raises below).
Chris@87 2453
Chris@87 2454 Parameters
Chris@87 2455 ----------
Chris@87 2456 x : array_like, dtype float or complex
Chris@87 2457 Argument of the Bessel function.
Chris@87 2458
Chris@87 2459 Returns
Chris@87 2460 -------
Chris@87 2461 out : ndarray, shape = x.shape, dtype = x.dtype
Chris@87 2462 The modified Bessel function evaluated at each of the elements of `x`.
Chris@87 2463
Chris@87 2464 Raises
Chris@87 2465 ------
Chris@87 2466 TypeError: array cannot be safely cast to required type
Chris@87 2467 If argument consists exclusively of int dtypes.
Chris@87 2468
Chris@87 2469 See Also
Chris@87 2470 --------
Chris@87 2471 scipy.special.iv, scipy.special.ive
Chris@87 2472
Chris@87 2473 Notes
Chris@87 2474 -----
Chris@87 2475 We use the algorithm published by Clenshaw [1]_ and referenced by
Chris@87 2476 Abramowitz and Stegun [2]_, for which the function domain is
Chris@87 2477 partitioned into the two intervals [0,8] and (8,inf), and Chebyshev
Chris@87 2478 polynomial expansions are employed in each interval. Relative error on
Chris@87 2479 the domain [0,30] using IEEE arithmetic is documented [3]_ as having a
Chris@87 2480 peak of 5.8e-16 with an rms of 1.4e-16 (n = 30000).
Chris@87 2481
Chris@87 2482 References
Chris@87 2483 ----------
Chris@87 2484 .. [1] C. W. Clenshaw, "Chebyshev series for mathematical functions", in
Chris@87 2485 *National Physical Laboratory Mathematical Tables*, vol. 5, London:
Chris@87 2486 Her Majesty's Stationery Office, 1962.
Chris@87 2487 .. [2] M. Abramowitz and I. A. Stegun, *Handbook of Mathematical
Chris@87 2488 Functions*, 10th printing, New York: Dover, 1964, pp. 379.
Chris@87 2489 http://www.math.sfu.ca/~cbm/aands/page_379.htm
Chris@87 2490 .. [3] http://kobesearch.cpan.org/htdocs/Math-Cephes/Math/Cephes.html
Chris@87 2491
Chris@87 2492 Examples
Chris@87 2493 --------
Chris@87 2494 >>> np.i0([0.])
Chris@87 2495 array(1.0)
Chris@87 2496 >>> np.i0([0., 1. + 2j])
Chris@87 2497 array([ 1.00000000+0.j , 0.18785373+0.64616944j])
Chris@87 2498
Chris@87 2499 """
Chris@87 2500 x = atleast_1d(x).copy()
Chris@87 2501 y = empty_like(x)
Chris@87 2502 ind = (x < 0)
Chris@87 2503 x[ind] = -x[ind]
Chris@87 2504 ind = (x <= 8.0)
Chris@87 2505 y[ind] = _i0_1(x[ind])
Chris@87 2506 ind2 = ~ind
Chris@87 2507 y[ind2] = _i0_2(x[ind2])
Chris@87 2508 return y.squeeze()
Chris@87 2509
Chris@87 2510 ## End of cephes code for i0
Chris@87 2511
Chris@87 2512
Chris@87 2513 def kaiser(M, beta):
Chris@87 2514 """
Chris@87 2515 Return the Kaiser window.
Chris@87 2516
Chris@87 2517 The Kaiser window is a taper formed by using a Bessel function.
Chris@87 2518
Chris@87 2519 Parameters
Chris@87 2520 ----------
Chris@87 2521 M : int
Chris@87 2522 Number of points in the output window. If zero or less, an
Chris@87 2523 empty array is returned.
Chris@87 2524 beta : float
Chris@87 2525 Shape parameter for window.
Chris@87 2526
Chris@87 2527 Returns
Chris@87 2528 -------
Chris@87 2529 out : array
Chris@87 2530 The window, with the maximum value normalized to one (the value
Chris@87 2531 one appears only if the number of samples is odd).
Chris@87 2532
Chris@87 2533 See Also
Chris@87 2534 --------
Chris@87 2535 bartlett, blackman, hamming, hanning
Chris@87 2536
Chris@87 2537 Notes
Chris@87 2538 -----
Chris@87 2539 The Kaiser window is defined as
Chris@87 2540
Chris@87 2541 .. math:: w(n) = I_0\\left( \\beta \\sqrt{1-\\frac{4n^2}{(M-1)^2}}
Chris@87 2542 \\right)/I_0(\\beta)
Chris@87 2543
Chris@87 2544 with
Chris@87 2545
Chris@87 2546 .. math:: \\quad -\\frac{M-1}{2} \\leq n \\leq \\frac{M-1}{2},
Chris@87 2547
Chris@87 2548 where :math:`I_0` is the modified zeroth-order Bessel function.
Chris@87 2549
Chris@87 2550 The Kaiser was named for Jim Kaiser, who discovered a simple
Chris@87 2551 approximation to the DPSS window based on Bessel functions. The Kaiser
Chris@87 2552 window is a very good approximation to the Digital Prolate Spheroidal
Chris@87 2553 Sequence, or Slepian window, which is the transform which maximizes the
Chris@87 2554 energy in the main lobe of the window relative to total energy.
Chris@87 2555
Chris@87 2556 The Kaiser can approximate many other windows by varying the beta
Chris@87 2557 parameter.
Chris@87 2558
Chris@87 2559 ==== =======================
Chris@87 2560 beta Window shape
Chris@87 2561 ==== =======================
Chris@87 2562 0 Rectangular
Chris@87 2563 5 Similar to a Hamming
Chris@87 2564 6 Similar to a Hanning
Chris@87 2565 8.6 Similar to a Blackman
Chris@87 2566 ==== =======================
Chris@87 2567
Chris@87 2568 A beta value of 14 is probably a good starting point. Note that as beta
Chris@87 2569 gets large, the window narrows, and so the number of samples needs to be
Chris@87 2570 large enough to sample the increasingly narrow spike, otherwise NaNs will
Chris@87 2571 get returned.
Chris@87 2572
Chris@87 2573 Most references to the Kaiser window come from the signal processing
Chris@87 2574 literature, where it is used as one of many windowing functions for
Chris@87 2575 smoothing values. It is also known as an apodization (which means
Chris@87 2576 "removing the foot", i.e. smoothing discontinuities at the beginning
Chris@87 2577 and end of the sampled signal) or tapering function.
Chris@87 2578
Chris@87 2579 References
Chris@87 2580 ----------
Chris@87 2581 .. [1] J. F. Kaiser, "Digital Filters" - Ch 7 in "Systems analysis by
Chris@87 2582 digital computer", Editors: F.F. Kuo and J.F. Kaiser, p 218-285.
Chris@87 2583 John Wiley and Sons, New York, (1966).
Chris@87 2584 .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
Chris@87 2585 University of Alberta Press, 1975, pp. 177-178.
Chris@87 2586 .. [3] Wikipedia, "Window function",
Chris@87 2587 http://en.wikipedia.org/wiki/Window_function
Chris@87 2588
Chris@87 2589 Examples
Chris@87 2590 --------
Chris@87 2591 >>> np.kaiser(12, 14)
Chris@87 2592 array([ 7.72686684e-06, 3.46009194e-03, 4.65200189e-02,
Chris@87 2593 2.29737120e-01, 5.99885316e-01, 9.45674898e-01,
Chris@87 2594 9.45674898e-01, 5.99885316e-01, 2.29737120e-01,
Chris@87 2595 4.65200189e-02, 3.46009194e-03, 7.72686684e-06])
Chris@87 2596
Chris@87 2597
Chris@87 2598 Plot the window and the frequency response:
Chris@87 2599
Chris@87 2600 >>> from numpy.fft import fft, fftshift
Chris@87 2601 >>> window = np.kaiser(51, 14)
Chris@87 2602 >>> plt.plot(window)
Chris@87 2603 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2604 >>> plt.title("Kaiser window")
Chris@87 2605 <matplotlib.text.Text object at 0x...>
Chris@87 2606 >>> plt.ylabel("Amplitude")
Chris@87 2607 <matplotlib.text.Text object at 0x...>
Chris@87 2608 >>> plt.xlabel("Sample")
Chris@87 2609 <matplotlib.text.Text object at 0x...>
Chris@87 2610 >>> plt.show()
Chris@87 2611
Chris@87 2612 >>> plt.figure()
Chris@87 2613 <matplotlib.figure.Figure object at 0x...>
Chris@87 2614 >>> A = fft(window, 2048) / 25.5
Chris@87 2615 >>> mag = np.abs(fftshift(A))
Chris@87 2616 >>> freq = np.linspace(-0.5, 0.5, len(A))
Chris@87 2617 >>> response = 20 * np.log10(mag)
Chris@87 2618 >>> response = np.clip(response, -100, 100)
Chris@87 2619 >>> plt.plot(freq, response)
Chris@87 2620 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2621 >>> plt.title("Frequency response of Kaiser window")
Chris@87 2622 <matplotlib.text.Text object at 0x...>
Chris@87 2623 >>> plt.ylabel("Magnitude [dB]")
Chris@87 2624 <matplotlib.text.Text object at 0x...>
Chris@87 2625 >>> plt.xlabel("Normalized frequency [cycles per sample]")
Chris@87 2626 <matplotlib.text.Text object at 0x...>
Chris@87 2627 >>> plt.axis('tight')
Chris@87 2628 (-0.5, 0.5, -100.0, ...)
Chris@87 2629 >>> plt.show()
Chris@87 2630
Chris@87 2631 """
Chris@87 2632 from numpy.dual import i0
Chris@87 2633 if M == 1:
Chris@87 2634 return np.array([1.])
Chris@87 2635 n = arange(0, M)
Chris@87 2636 alpha = (M-1)/2.0
Chris@87 2637 return i0(beta * sqrt(1-((n-alpha)/alpha)**2.0))/i0(float(beta))
Chris@87 2638
Chris@87 2639
Chris@87 2640 def sinc(x):
Chris@87 2641 """
Chris@87 2642 Return the sinc function.
Chris@87 2643
Chris@87 2644 The sinc function is :math:`\\sin(\\pi x)/(\\pi x)`.
Chris@87 2645
Chris@87 2646 Parameters
Chris@87 2647 ----------
Chris@87 2648 x : ndarray
Chris@87 2649 Array (possibly multi-dimensional) of values for which to to
Chris@87 2650 calculate ``sinc(x)``.
Chris@87 2651
Chris@87 2652 Returns
Chris@87 2653 -------
Chris@87 2654 out : ndarray
Chris@87 2655 ``sinc(x)``, which has the same shape as the input.
Chris@87 2656
Chris@87 2657 Notes
Chris@87 2658 -----
Chris@87 2659 ``sinc(0)`` is the limit value 1.
Chris@87 2660
Chris@87 2661 The name sinc is short for "sine cardinal" or "sinus cardinalis".
Chris@87 2662
Chris@87 2663 The sinc function is used in various signal processing applications,
Chris@87 2664 including in anti-aliasing, in the construction of a Lanczos resampling
Chris@87 2665 filter, and in interpolation.
Chris@87 2666
Chris@87 2667 For bandlimited interpolation of discrete-time signals, the ideal
Chris@87 2668 interpolation kernel is proportional to the sinc function.
Chris@87 2669
Chris@87 2670 References
Chris@87 2671 ----------
Chris@87 2672 .. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
Chris@87 2673 Resource. http://mathworld.wolfram.com/SincFunction.html
Chris@87 2674 .. [2] Wikipedia, "Sinc function",
Chris@87 2675 http://en.wikipedia.org/wiki/Sinc_function
Chris@87 2676
Chris@87 2677 Examples
Chris@87 2678 --------
Chris@87 2679 >>> x = np.linspace(-4, 4, 41)
Chris@87 2680 >>> np.sinc(x)
Chris@87 2681 array([ -3.89804309e-17, -4.92362781e-02, -8.40918587e-02,
Chris@87 2682 -8.90384387e-02, -5.84680802e-02, 3.89804309e-17,
Chris@87 2683 6.68206631e-02, 1.16434881e-01, 1.26137788e-01,
Chris@87 2684 8.50444803e-02, -3.89804309e-17, -1.03943254e-01,
Chris@87 2685 -1.89206682e-01, -2.16236208e-01, -1.55914881e-01,
Chris@87 2686 3.89804309e-17, 2.33872321e-01, 5.04551152e-01,
Chris@87 2687 7.56826729e-01, 9.35489284e-01, 1.00000000e+00,
Chris@87 2688 9.35489284e-01, 7.56826729e-01, 5.04551152e-01,
Chris@87 2689 2.33872321e-01, 3.89804309e-17, -1.55914881e-01,
Chris@87 2690 -2.16236208e-01, -1.89206682e-01, -1.03943254e-01,
Chris@87 2691 -3.89804309e-17, 8.50444803e-02, 1.26137788e-01,
Chris@87 2692 1.16434881e-01, 6.68206631e-02, 3.89804309e-17,
Chris@87 2693 -5.84680802e-02, -8.90384387e-02, -8.40918587e-02,
Chris@87 2694 -4.92362781e-02, -3.89804309e-17])
Chris@87 2695
Chris@87 2696 >>> plt.plot(x, np.sinc(x))
Chris@87 2697 [<matplotlib.lines.Line2D object at 0x...>]
Chris@87 2698 >>> plt.title("Sinc Function")
Chris@87 2699 <matplotlib.text.Text object at 0x...>
Chris@87 2700 >>> plt.ylabel("Amplitude")
Chris@87 2701 <matplotlib.text.Text object at 0x...>
Chris@87 2702 >>> plt.xlabel("X")
Chris@87 2703 <matplotlib.text.Text object at 0x...>
Chris@87 2704 >>> plt.show()
Chris@87 2705
Chris@87 2706 It works in 2-D as well:
Chris@87 2707
Chris@87 2708 >>> x = np.linspace(-4, 4, 401)
Chris@87 2709 >>> xx = np.outer(x, x)
Chris@87 2710 >>> plt.imshow(np.sinc(xx))
Chris@87 2711 <matplotlib.image.AxesImage object at 0x...>
Chris@87 2712
Chris@87 2713 """
Chris@87 2714 x = np.asanyarray(x)
Chris@87 2715 y = pi * where(x == 0, 1.0e-20, x)
Chris@87 2716 return sin(y)/y
Chris@87 2717
Chris@87 2718
Chris@87 2719 def msort(a):
Chris@87 2720 """
Chris@87 2721 Return a copy of an array sorted along the first axis.
Chris@87 2722
Chris@87 2723 Parameters
Chris@87 2724 ----------
Chris@87 2725 a : array_like
Chris@87 2726 Array to be sorted.
Chris@87 2727
Chris@87 2728 Returns
Chris@87 2729 -------
Chris@87 2730 sorted_array : ndarray
Chris@87 2731 Array of the same type and shape as `a`.
Chris@87 2732
Chris@87 2733 See Also
Chris@87 2734 --------
Chris@87 2735 sort
Chris@87 2736
Chris@87 2737 Notes
Chris@87 2738 -----
Chris@87 2739 ``np.msort(a)`` is equivalent to ``np.sort(a, axis=0)``.
Chris@87 2740
Chris@87 2741 """
Chris@87 2742 b = array(a, subok=True, copy=True)
Chris@87 2743 b.sort(0)
Chris@87 2744 return b
Chris@87 2745
Chris@87 2746
Chris@87 2747 def _ureduce(a, func, **kwargs):
Chris@87 2748 """
Chris@87 2749 Internal Function.
Chris@87 2750 Call `func` with `a` as first argument swapping the axes to use extended
Chris@87 2751 axis on functions that don't support it natively.
Chris@87 2752
Chris@87 2753 Returns result and a.shape with axis dims set to 1.
Chris@87 2754
Chris@87 2755 Parameters
Chris@87 2756 ----------
Chris@87 2757 a : array_like
Chris@87 2758 Input array or object that can be converted to an array.
Chris@87 2759 func : callable
Chris@87 2760 Reduction function Kapable of receiving an axis argument.
Chris@87 2761 It is is called with `a` as first argument followed by `kwargs`.
Chris@87 2762 kwargs : keyword arguments
Chris@87 2763 additional keyword arguments to pass to `func`.
Chris@87 2764
Chris@87 2765 Returns
Chris@87 2766 -------
Chris@87 2767 result : tuple
Chris@87 2768 Result of func(a, **kwargs) and a.shape with axis dims set to 1
Chris@87 2769 which can be used to reshape the result to the same shape a ufunc with
Chris@87 2770 keepdims=True would produce.
Chris@87 2771
Chris@87 2772 """
Chris@87 2773 a = np.asanyarray(a)
Chris@87 2774 axis = kwargs.get('axis', None)
Chris@87 2775 if axis is not None:
Chris@87 2776 keepdim = list(a.shape)
Chris@87 2777 nd = a.ndim
Chris@87 2778 try:
Chris@87 2779 axis = operator.index(axis)
Chris@87 2780 if axis >= nd or axis < -nd:
Chris@87 2781 raise IndexError("axis %d out of bounds (%d)" % (axis, a.ndim))
Chris@87 2782 keepdim[axis] = 1
Chris@87 2783 except TypeError:
Chris@87 2784 sax = set()
Chris@87 2785 for x in axis:
Chris@87 2786 if x >= nd or x < -nd:
Chris@87 2787 raise IndexError("axis %d out of bounds (%d)" % (x, nd))
Chris@87 2788 if x in sax:
Chris@87 2789 raise ValueError("duplicate value in axis")
Chris@87 2790 sax.add(x % nd)
Chris@87 2791 keepdim[x] = 1
Chris@87 2792 keep = sax.symmetric_difference(frozenset(range(nd)))
Chris@87 2793 nkeep = len(keep)
Chris@87 2794 # swap axis that should not be reduced to front
Chris@87 2795 for i, s in enumerate(sorted(keep)):
Chris@87 2796 a = a.swapaxes(i, s)
Chris@87 2797 # merge reduced axis
Chris@87 2798 a = a.reshape(a.shape[:nkeep] + (-1,))
Chris@87 2799 kwargs['axis'] = -1
Chris@87 2800 else:
Chris@87 2801 keepdim = [1] * a.ndim
Chris@87 2802
Chris@87 2803 r = func(a, **kwargs)
Chris@87 2804 return r, keepdim
Chris@87 2805
Chris@87 2806
Chris@87 2807 def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
Chris@87 2808 """
Chris@87 2809 Compute the median along the specified axis.
Chris@87 2810
Chris@87 2811 Returns the median of the array elements.
Chris@87 2812
Chris@87 2813 Parameters
Chris@87 2814 ----------
Chris@87 2815 a : array_like
Chris@87 2816 Input array or object that can be converted to an array.
Chris@87 2817 axis : int or sequence of int, optional
Chris@87 2818 Axis along which the medians are computed. The default (axis=None)
Chris@87 2819 is to compute the median along a flattened version of the array.
Chris@87 2820 A sequence of axes is supported since version 1.9.0.
Chris@87 2821 out : ndarray, optional
Chris@87 2822 Alternative output array in which to place the result. It must have
Chris@87 2823 the same shape and buffer length as the expected output, but the
Chris@87 2824 type (of the output) will be cast if necessary.
Chris@87 2825 overwrite_input : bool, optional
Chris@87 2826 If True, then allow use of memory of input array (a) for
Chris@87 2827 calculations. The input array will be modified by the call to
Chris@87 2828 median. This will save memory when you do not need to preserve the
Chris@87 2829 contents of the input array. Treat the input as undefined, but it
Chris@87 2830 will probably be fully or partially sorted. Default is False. Note
Chris@87 2831 that, if `overwrite_input` is True and the input is not already an
Chris@87 2832 ndarray, an error will be raised.
Chris@87 2833 keepdims : bool, optional
Chris@87 2834 If this is set to True, the axes which are reduced are left
Chris@87 2835 in the result as dimensions with size one. With this option,
Chris@87 2836 the result will broadcast correctly against the original `arr`.
Chris@87 2837
Chris@87 2838 .. versionadded:: 1.9.0
Chris@87 2839
Chris@87 2840
Chris@87 2841 Returns
Chris@87 2842 -------
Chris@87 2843 median : ndarray
Chris@87 2844 A new array holding the result (unless `out` is specified, in which
Chris@87 2845 case that array is returned instead). If the input contains
Chris@87 2846 integers, or floats of smaller precision than 64, then the output
Chris@87 2847 data-type is float64. Otherwise, the output data-type is the same
Chris@87 2848 as that of the input.
Chris@87 2849
Chris@87 2850 See Also
Chris@87 2851 --------
Chris@87 2852 mean, percentile
Chris@87 2853
Chris@87 2854 Notes
Chris@87 2855 -----
Chris@87 2856 Given a vector V of length N, the median of V is the middle value of
Chris@87 2857 a sorted copy of V, ``V_sorted`` - i.e., ``V_sorted[(N-1)/2]``, when N is
Chris@87 2858 odd. When N is even, it is the average of the two middle values of
Chris@87 2859 ``V_sorted``.
Chris@87 2860
Chris@87 2861 Examples
Chris@87 2862 --------
Chris@87 2863 >>> a = np.array([[10, 7, 4], [3, 2, 1]])
Chris@87 2864 >>> a
Chris@87 2865 array([[10, 7, 4],
Chris@87 2866 [ 3, 2, 1]])
Chris@87 2867 >>> np.median(a)
Chris@87 2868 3.5
Chris@87 2869 >>> np.median(a, axis=0)
Chris@87 2870 array([ 6.5, 4.5, 2.5])
Chris@87 2871 >>> np.median(a, axis=1)
Chris@87 2872 array([ 7., 2.])
Chris@87 2873 >>> m = np.median(a, axis=0)
Chris@87 2874 >>> out = np.zeros_like(m)
Chris@87 2875 >>> np.median(a, axis=0, out=m)
Chris@87 2876 array([ 6.5, 4.5, 2.5])
Chris@87 2877 >>> m
Chris@87 2878 array([ 6.5, 4.5, 2.5])
Chris@87 2879 >>> b = a.copy()
Chris@87 2880 >>> np.median(b, axis=1, overwrite_input=True)
Chris@87 2881 array([ 7., 2.])
Chris@87 2882 >>> assert not np.all(a==b)
Chris@87 2883 >>> b = a.copy()
Chris@87 2884 >>> np.median(b, axis=None, overwrite_input=True)
Chris@87 2885 3.5
Chris@87 2886 >>> assert not np.all(a==b)
Chris@87 2887
Chris@87 2888 """
Chris@87 2889 r, k = _ureduce(a, func=_median, axis=axis, out=out,
Chris@87 2890 overwrite_input=overwrite_input)
Chris@87 2891 if keepdims:
Chris@87 2892 return r.reshape(k)
Chris@87 2893 else:
Chris@87 2894 return r
Chris@87 2895
Chris@87 2896 def _median(a, axis=None, out=None, overwrite_input=False):
Chris@87 2897 # can't be reasonably be implemented in terms of percentile as we have to
Chris@87 2898 # call mean to not break astropy
Chris@87 2899 a = np.asanyarray(a)
Chris@87 2900 if axis is not None and axis >= a.ndim:
Chris@87 2901 raise IndexError(
Chris@87 2902 "axis %d out of bounds (%d)" % (axis, a.ndim))
Chris@87 2903
Chris@87 2904 if overwrite_input:
Chris@87 2905 if axis is None:
Chris@87 2906 part = a.ravel()
Chris@87 2907 sz = part.size
Chris@87 2908 if sz % 2 == 0:
Chris@87 2909 szh = sz // 2
Chris@87 2910 part.partition((szh - 1, szh))
Chris@87 2911 else:
Chris@87 2912 part.partition((sz - 1) // 2)
Chris@87 2913 else:
Chris@87 2914 sz = a.shape[axis]
Chris@87 2915 if sz % 2 == 0:
Chris@87 2916 szh = sz // 2
Chris@87 2917 a.partition((szh - 1, szh), axis=axis)
Chris@87 2918 else:
Chris@87 2919 a.partition((sz - 1) // 2, axis=axis)
Chris@87 2920 part = a
Chris@87 2921 else:
Chris@87 2922 if axis is None:
Chris@87 2923 sz = a.size
Chris@87 2924 else:
Chris@87 2925 sz = a.shape[axis]
Chris@87 2926 if sz % 2 == 0:
Chris@87 2927 part = partition(a, ((sz // 2) - 1, sz // 2), axis=axis)
Chris@87 2928 else:
Chris@87 2929 part = partition(a, (sz - 1) // 2, axis=axis)
Chris@87 2930 if part.shape == ():
Chris@87 2931 # make 0-D arrays work
Chris@87 2932 return part.item()
Chris@87 2933 if axis is None:
Chris@87 2934 axis = 0
Chris@87 2935 indexer = [slice(None)] * part.ndim
Chris@87 2936 index = part.shape[axis] // 2
Chris@87 2937 if part.shape[axis] % 2 == 1:
Chris@87 2938 # index with slice to allow mean (below) to work
Chris@87 2939 indexer[axis] = slice(index, index+1)
Chris@87 2940 else:
Chris@87 2941 indexer[axis] = slice(index-1, index+1)
Chris@87 2942 # Use mean in odd and even case to coerce data type
Chris@87 2943 # and check, use out array.
Chris@87 2944 return mean(part[indexer], axis=axis, out=out)
Chris@87 2945
Chris@87 2946
Chris@87 2947 def percentile(a, q, axis=None, out=None,
Chris@87 2948 overwrite_input=False, interpolation='linear', keepdims=False):
Chris@87 2949 """
Chris@87 2950 Compute the qth percentile of the data along the specified axis.
Chris@87 2951
Chris@87 2952 Returns the qth percentile of the array elements.
Chris@87 2953
Chris@87 2954 Parameters
Chris@87 2955 ----------
Chris@87 2956 a : array_like
Chris@87 2957 Input array or object that can be converted to an array.
Chris@87 2958 q : float in range of [0,100] (or sequence of floats)
Chris@87 2959 Percentile to compute which must be between 0 and 100 inclusive.
Chris@87 2960 axis : int or sequence of int, optional
Chris@87 2961 Axis along which the percentiles are computed. The default (None)
Chris@87 2962 is to compute the percentiles along a flattened version of the array.
Chris@87 2963 A sequence of axes is supported since version 1.9.0.
Chris@87 2964 out : ndarray, optional
Chris@87 2965 Alternative output array in which to place the result. It must
Chris@87 2966 have the same shape and buffer length as the expected output,
Chris@87 2967 but the type (of the output) will be cast if necessary.
Chris@87 2968 overwrite_input : bool, optional
Chris@87 2969 If True, then allow use of memory of input array `a` for
Chris@87 2970 calculations. The input array will be modified by the call to
Chris@87 2971 percentile. This will save memory when you do not need to preserve
Chris@87 2972 the contents of the input array. In this case you should not make
Chris@87 2973 any assumptions about the content of the passed in array `a` after
Chris@87 2974 this function completes -- treat it as undefined. Default is False.
Chris@87 2975 Note that, if the `a` input is not already an array this parameter
Chris@87 2976 will have no effect, `a` will be converted to an array internally
Chris@87 2977 regardless of the value of this parameter.
Chris@87 2978 interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}
Chris@87 2979 This optional parameter specifies the interpolation method to use,
Chris@87 2980 when the desired quantile lies between two data points `i` and `j`:
Chris@87 2981 * linear: `i + (j - i) * fraction`, where `fraction` is the
Chris@87 2982 fractional part of the index surrounded by `i` and `j`.
Chris@87 2983 * lower: `i`.
Chris@87 2984 * higher: `j`.
Chris@87 2985 * nearest: `i` or `j` whichever is nearest.
Chris@87 2986 * midpoint: (`i` + `j`) / 2.
Chris@87 2987
Chris@87 2988 .. versionadded:: 1.9.0
Chris@87 2989 keepdims : bool, optional
Chris@87 2990 If this is set to True, the axes which are reduced are left
Chris@87 2991 in the result as dimensions with size one. With this option,
Chris@87 2992 the result will broadcast correctly against the original `arr`.
Chris@87 2993
Chris@87 2994 .. versionadded:: 1.9.0
Chris@87 2995
Chris@87 2996 Returns
Chris@87 2997 -------
Chris@87 2998 percentile : scalar or ndarray
Chris@87 2999 If a single percentile `q` is given and axis=None a scalar is
Chris@87 3000 returned. If multiple percentiles `q` are given an array holding
Chris@87 3001 the result is returned. The results are listed in the first axis.
Chris@87 3002 (If `out` is specified, in which case that array is returned
Chris@87 3003 instead). If the input contains integers, or floats of smaller
Chris@87 3004 precision than 64, then the output data-type is float64. Otherwise,
Chris@87 3005 the output data-type is the same as that of the input.
Chris@87 3006
Chris@87 3007 See Also
Chris@87 3008 --------
Chris@87 3009 mean, median
Chris@87 3010
Chris@87 3011 Notes
Chris@87 3012 -----
Chris@87 3013 Given a vector V of length N, the q-th percentile of V is the q-th ranked
Chris@87 3014 value in a sorted copy of V. The values and distances of the two
Chris@87 3015 nearest neighbors as well as the `interpolation` parameter will
Chris@87 3016 determine the percentile if the normalized ranking does not match q
Chris@87 3017 exactly. This function is the same as the median if ``q=50``, the same
Chris@87 3018 as the minimum if ``q=0`` and the same as the maximum if ``q=100``.
Chris@87 3019
Chris@87 3020 Examples
Chris@87 3021 --------
Chris@87 3022 >>> a = np.array([[10, 7, 4], [3, 2, 1]])
Chris@87 3023 >>> a
Chris@87 3024 array([[10, 7, 4],
Chris@87 3025 [ 3, 2, 1]])
Chris@87 3026 >>> np.percentile(a, 50)
Chris@87 3027 array([ 3.5])
Chris@87 3028 >>> np.percentile(a, 50, axis=0)
Chris@87 3029 array([[ 6.5, 4.5, 2.5]])
Chris@87 3030 >>> np.percentile(a, 50, axis=1)
Chris@87 3031 array([[ 7.],
Chris@87 3032 [ 2.]])
Chris@87 3033
Chris@87 3034 >>> m = np.percentile(a, 50, axis=0)
Chris@87 3035 >>> out = np.zeros_like(m)
Chris@87 3036 >>> np.percentile(a, 50, axis=0, out=m)
Chris@87 3037 array([[ 6.5, 4.5, 2.5]])
Chris@87 3038 >>> m
Chris@87 3039 array([[ 6.5, 4.5, 2.5]])
Chris@87 3040
Chris@87 3041 >>> b = a.copy()
Chris@87 3042 >>> np.percentile(b, 50, axis=1, overwrite_input=True)
Chris@87 3043 array([[ 7.],
Chris@87 3044 [ 2.]])
Chris@87 3045 >>> assert not np.all(a==b)
Chris@87 3046 >>> b = a.copy()
Chris@87 3047 >>> np.percentile(b, 50, axis=None, overwrite_input=True)
Chris@87 3048 array([ 3.5])
Chris@87 3049
Chris@87 3050 """
Chris@87 3051 q = array(q, dtype=np.float64, copy=True)
Chris@87 3052 r, k = _ureduce(a, func=_percentile, q=q, axis=axis, out=out,
Chris@87 3053 overwrite_input=overwrite_input,
Chris@87 3054 interpolation=interpolation)
Chris@87 3055 if keepdims:
Chris@87 3056 if q.ndim == 0:
Chris@87 3057 return r.reshape(k)
Chris@87 3058 else:
Chris@87 3059 return r.reshape([len(q)] + k)
Chris@87 3060 else:
Chris@87 3061 return r
Chris@87 3062
Chris@87 3063
Chris@87 3064 def _percentile(a, q, axis=None, out=None,
Chris@87 3065 overwrite_input=False, interpolation='linear', keepdims=False):
Chris@87 3066 a = asarray(a)
Chris@87 3067 if q.ndim == 0:
Chris@87 3068 # Do not allow 0-d arrays because following code fails for scalar
Chris@87 3069 zerod = True
Chris@87 3070 q = q[None]
Chris@87 3071 else:
Chris@87 3072 zerod = False
Chris@87 3073
Chris@87 3074 # avoid expensive reductions, relevant for arrays with < O(1000) elements
Chris@87 3075 if q.size < 10:
Chris@87 3076 for i in range(q.size):
Chris@87 3077 if q[i] < 0. or q[i] > 100.:
Chris@87 3078 raise ValueError("Percentiles must be in the range [0,100]")
Chris@87 3079 q[i] /= 100.
Chris@87 3080 else:
Chris@87 3081 # faster than any()
Chris@87 3082 if np.count_nonzero(q < 0.) or np.count_nonzero(q > 100.):
Chris@87 3083 raise ValueError("Percentiles must be in the range [0,100]")
Chris@87 3084 q /= 100.
Chris@87 3085
Chris@87 3086 # prepare a for partioning
Chris@87 3087 if overwrite_input:
Chris@87 3088 if axis is None:
Chris@87 3089 ap = a.ravel()
Chris@87 3090 else:
Chris@87 3091 ap = a
Chris@87 3092 else:
Chris@87 3093 if axis is None:
Chris@87 3094 ap = a.flatten()
Chris@87 3095 else:
Chris@87 3096 ap = a.copy()
Chris@87 3097
Chris@87 3098 if axis is None:
Chris@87 3099 axis = 0
Chris@87 3100
Chris@87 3101 Nx = ap.shape[axis]
Chris@87 3102 indices = q * (Nx - 1)
Chris@87 3103
Chris@87 3104 # round fractional indices according to interpolation method
Chris@87 3105 if interpolation == 'lower':
Chris@87 3106 indices = floor(indices).astype(intp)
Chris@87 3107 elif interpolation == 'higher':
Chris@87 3108 indices = ceil(indices).astype(intp)
Chris@87 3109 elif interpolation == 'midpoint':
Chris@87 3110 indices = floor(indices) + 0.5
Chris@87 3111 elif interpolation == 'nearest':
Chris@87 3112 indices = around(indices).astype(intp)
Chris@87 3113 elif interpolation == 'linear':
Chris@87 3114 pass # keep index as fraction and interpolate
Chris@87 3115 else:
Chris@87 3116 raise ValueError(
Chris@87 3117 "interpolation can only be 'linear', 'lower' 'higher', "
Chris@87 3118 "'midpoint', or 'nearest'")
Chris@87 3119
Chris@87 3120 if indices.dtype == intp: # take the points along axis
Chris@87 3121 ap.partition(indices, axis=axis)
Chris@87 3122 # ensure axis with qth is first
Chris@87 3123 ap = np.rollaxis(ap, axis, 0)
Chris@87 3124 axis = 0
Chris@87 3125
Chris@87 3126 if zerod:
Chris@87 3127 indices = indices[0]
Chris@87 3128 r = take(ap, indices, axis=axis, out=out)
Chris@87 3129 else: # weight the points above and below the indices
Chris@87 3130 indices_below = floor(indices).astype(intp)
Chris@87 3131 indices_above = indices_below + 1
Chris@87 3132 indices_above[indices_above > Nx - 1] = Nx - 1
Chris@87 3133
Chris@87 3134 weights_above = indices - indices_below
Chris@87 3135 weights_below = 1.0 - weights_above
Chris@87 3136
Chris@87 3137 weights_shape = [1, ] * ap.ndim
Chris@87 3138 weights_shape[axis] = len(indices)
Chris@87 3139 weights_below.shape = weights_shape
Chris@87 3140 weights_above.shape = weights_shape
Chris@87 3141
Chris@87 3142 ap.partition(concatenate((indices_below, indices_above)), axis=axis)
Chris@87 3143 x1 = take(ap, indices_below, axis=axis) * weights_below
Chris@87 3144 x2 = take(ap, indices_above, axis=axis) * weights_above
Chris@87 3145
Chris@87 3146 # ensure axis with qth is first
Chris@87 3147 x1 = np.rollaxis(x1, axis, 0)
Chris@87 3148 x2 = np.rollaxis(x2, axis, 0)
Chris@87 3149
Chris@87 3150 if zerod:
Chris@87 3151 x1 = x1.squeeze(0)
Chris@87 3152 x2 = x2.squeeze(0)
Chris@87 3153
Chris@87 3154 if out is not None:
Chris@87 3155 r = add(x1, x2, out=out)
Chris@87 3156 else:
Chris@87 3157 r = add(x1, x2)
Chris@87 3158
Chris@87 3159 return r
Chris@87 3160
Chris@87 3161
Chris@87 3162 def trapz(y, x=None, dx=1.0, axis=-1):
Chris@87 3163 """
Chris@87 3164 Integrate along the given axis using the composite trapezoidal rule.
Chris@87 3165
Chris@87 3166 Integrate `y` (`x`) along given axis.
Chris@87 3167
Chris@87 3168 Parameters
Chris@87 3169 ----------
Chris@87 3170 y : array_like
Chris@87 3171 Input array to integrate.
Chris@87 3172 x : array_like, optional
Chris@87 3173 If `x` is None, then spacing between all `y` elements is `dx`.
Chris@87 3174 dx : scalar, optional
Chris@87 3175 If `x` is None, spacing given by `dx` is assumed. Default is 1.
Chris@87 3176 axis : int, optional
Chris@87 3177 Specify the axis.
Chris@87 3178
Chris@87 3179 Returns
Chris@87 3180 -------
Chris@87 3181 trapz : float
Chris@87 3182 Definite integral as approximated by trapezoidal rule.
Chris@87 3183
Chris@87 3184 See Also
Chris@87 3185 --------
Chris@87 3186 sum, cumsum
Chris@87 3187
Chris@87 3188 Notes
Chris@87 3189 -----
Chris@87 3190 Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
Chris@87 3191 will be taken from `y` array, by default x-axis distances between
Chris@87 3192 points will be 1.0, alternatively they can be provided with `x` array
Chris@87 3193 or with `dx` scalar. Return value will be equal to combined area under
Chris@87 3194 the red lines.
Chris@87 3195
Chris@87 3196
Chris@87 3197 References
Chris@87 3198 ----------
Chris@87 3199 .. [1] Wikipedia page: http://en.wikipedia.org/wiki/Trapezoidal_rule
Chris@87 3200
Chris@87 3201 .. [2] Illustration image:
Chris@87 3202 http://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png
Chris@87 3203
Chris@87 3204 Examples
Chris@87 3205 --------
Chris@87 3206 >>> np.trapz([1,2,3])
Chris@87 3207 4.0
Chris@87 3208 >>> np.trapz([1,2,3], x=[4,6,8])
Chris@87 3209 8.0
Chris@87 3210 >>> np.trapz([1,2,3], dx=2)
Chris@87 3211 8.0
Chris@87 3212 >>> a = np.arange(6).reshape(2, 3)
Chris@87 3213 >>> a
Chris@87 3214 array([[0, 1, 2],
Chris@87 3215 [3, 4, 5]])
Chris@87 3216 >>> np.trapz(a, axis=0)
Chris@87 3217 array([ 1.5, 2.5, 3.5])
Chris@87 3218 >>> np.trapz(a, axis=1)
Chris@87 3219 array([ 2., 8.])
Chris@87 3220
Chris@87 3221 """
Chris@87 3222 y = asanyarray(y)
Chris@87 3223 if x is None:
Chris@87 3224 d = dx
Chris@87 3225 else:
Chris@87 3226 x = asanyarray(x)
Chris@87 3227 if x.ndim == 1:
Chris@87 3228 d = diff(x)
Chris@87 3229 # reshape to correct shape
Chris@87 3230 shape = [1]*y.ndim
Chris@87 3231 shape[axis] = d.shape[0]
Chris@87 3232 d = d.reshape(shape)
Chris@87 3233 else:
Chris@87 3234 d = diff(x, axis=axis)
Chris@87 3235 nd = len(y.shape)
Chris@87 3236 slice1 = [slice(None)]*nd
Chris@87 3237 slice2 = [slice(None)]*nd
Chris@87 3238 slice1[axis] = slice(1, None)
Chris@87 3239 slice2[axis] = slice(None, -1)
Chris@87 3240 try:
Chris@87 3241 ret = (d * (y[slice1] + y[slice2]) / 2.0).sum(axis)
Chris@87 3242 except ValueError:
Chris@87 3243 # Operations didn't work, cast to ndarray
Chris@87 3244 d = np.asarray(d)
Chris@87 3245 y = np.asarray(y)
Chris@87 3246 ret = add.reduce(d * (y[slice1]+y[slice2])/2.0, axis)
Chris@87 3247 return ret
Chris@87 3248
Chris@87 3249
Chris@87 3250 #always succeed
Chris@87 3251 def add_newdoc(place, obj, doc):
Chris@87 3252 """Adds documentation to obj which is in module place.
Chris@87 3253
Chris@87 3254 If doc is a string add it to obj as a docstring
Chris@87 3255
Chris@87 3256 If doc is a tuple, then the first element is interpreted as
Chris@87 3257 an attribute of obj and the second as the docstring
Chris@87 3258 (method, docstring)
Chris@87 3259
Chris@87 3260 If doc is a list, then each element of the list should be a
Chris@87 3261 sequence of length two --> [(method1, docstring1),
Chris@87 3262 (method2, docstring2), ...]
Chris@87 3263
Chris@87 3264 This routine never raises an error.
Chris@87 3265
Chris@87 3266 This routine cannot modify read-only docstrings, as appear
Chris@87 3267 in new-style classes or built-in functions. Because this
Chris@87 3268 routine never raises an error the caller must check manually
Chris@87 3269 that the docstrings were changed.
Chris@87 3270 """
Chris@87 3271 try:
Chris@87 3272 new = getattr(__import__(place, globals(), {}, [obj]), obj)
Chris@87 3273 if isinstance(doc, str):
Chris@87 3274 add_docstring(new, doc.strip())
Chris@87 3275 elif isinstance(doc, tuple):
Chris@87 3276 add_docstring(getattr(new, doc[0]), doc[1].strip())
Chris@87 3277 elif isinstance(doc, list):
Chris@87 3278 for val in doc:
Chris@87 3279 add_docstring(getattr(new, val[0]), val[1].strip())
Chris@87 3280 except:
Chris@87 3281 pass
Chris@87 3282
Chris@87 3283
Chris@87 3284 # Based on scitools meshgrid
Chris@87 3285 def meshgrid(*xi, **kwargs):
Chris@87 3286 """
Chris@87 3287 Return coordinate matrices from coordinate vectors.
Chris@87 3288
Chris@87 3289 Make N-D coordinate arrays for vectorized evaluations of
Chris@87 3290 N-D scalar/vector fields over N-D grids, given
Chris@87 3291 one-dimensional coordinate arrays x1, x2,..., xn.
Chris@87 3292
Chris@87 3293 .. versionchanged:: 1.9
Chris@87 3294 1-D and 0-D cases are allowed.
Chris@87 3295
Chris@87 3296 Parameters
Chris@87 3297 ----------
Chris@87 3298 x1, x2,..., xn : array_like
Chris@87 3299 1-D arrays representing the coordinates of a grid.
Chris@87 3300 indexing : {'xy', 'ij'}, optional
Chris@87 3301 Cartesian ('xy', default) or matrix ('ij') indexing of output.
Chris@87 3302 See Notes for more details.
Chris@87 3303
Chris@87 3304 .. versionadded:: 1.7.0
Chris@87 3305 sparse : bool, optional
Chris@87 3306 If True a sparse grid is returned in order to conserve memory.
Chris@87 3307 Default is False.
Chris@87 3308
Chris@87 3309 .. versionadded:: 1.7.0
Chris@87 3310 copy : bool, optional
Chris@87 3311 If False, a view into the original arrays are returned in order to
Chris@87 3312 conserve memory. Default is True. Please note that
Chris@87 3313 ``sparse=False, copy=False`` will likely return non-contiguous
Chris@87 3314 arrays. Furthermore, more than one element of a broadcast array
Chris@87 3315 may refer to a single memory location. If you need to write to the
Chris@87 3316 arrays, make copies first.
Chris@87 3317
Chris@87 3318 .. versionadded:: 1.7.0
Chris@87 3319
Chris@87 3320 Returns
Chris@87 3321 -------
Chris@87 3322 X1, X2,..., XN : ndarray
Chris@87 3323 For vectors `x1`, `x2`,..., 'xn' with lengths ``Ni=len(xi)`` ,
Chris@87 3324 return ``(N1, N2, N3,...Nn)`` shaped arrays if indexing='ij'
Chris@87 3325 or ``(N2, N1, N3,...Nn)`` shaped arrays if indexing='xy'
Chris@87 3326 with the elements of `xi` repeated to fill the matrix along
Chris@87 3327 the first dimension for `x1`, the second for `x2` and so on.
Chris@87 3328
Chris@87 3329 Notes
Chris@87 3330 -----
Chris@87 3331 This function supports both indexing conventions through the indexing
Chris@87 3332 keyword argument. Giving the string 'ij' returns a meshgrid with
Chris@87 3333 matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing.
Chris@87 3334 In the 2-D case with inputs of length M and N, the outputs are of shape
Chris@87 3335 (N, M) for 'xy' indexing and (M, N) for 'ij' indexing. In the 3-D case
Chris@87 3336 with inputs of length M, N and P, outputs are of shape (N, M, P) for
Chris@87 3337 'xy' indexing and (M, N, P) for 'ij' indexing. The difference is
Chris@87 3338 illustrated by the following code snippet::
Chris@87 3339
Chris@87 3340 xv, yv = meshgrid(x, y, sparse=False, indexing='ij')
Chris@87 3341 for i in range(nx):
Chris@87 3342 for j in range(ny):
Chris@87 3343 # treat xv[i,j], yv[i,j]
Chris@87 3344
Chris@87 3345 xv, yv = meshgrid(x, y, sparse=False, indexing='xy')
Chris@87 3346 for i in range(nx):
Chris@87 3347 for j in range(ny):
Chris@87 3348 # treat xv[j,i], yv[j,i]
Chris@87 3349
Chris@87 3350 In the 1-D and 0-D case, the indexing and sparse keywords have no effect.
Chris@87 3351
Chris@87 3352 See Also
Chris@87 3353 --------
Chris@87 3354 index_tricks.mgrid : Construct a multi-dimensional "meshgrid"
Chris@87 3355 using indexing notation.
Chris@87 3356 index_tricks.ogrid : Construct an open multi-dimensional "meshgrid"
Chris@87 3357 using indexing notation.
Chris@87 3358
Chris@87 3359 Examples
Chris@87 3360 --------
Chris@87 3361 >>> nx, ny = (3, 2)
Chris@87 3362 >>> x = np.linspace(0, 1, nx)
Chris@87 3363 >>> y = np.linspace(0, 1, ny)
Chris@87 3364 >>> xv, yv = meshgrid(x, y)
Chris@87 3365 >>> xv
Chris@87 3366 array([[ 0. , 0.5, 1. ],
Chris@87 3367 [ 0. , 0.5, 1. ]])
Chris@87 3368 >>> yv
Chris@87 3369 array([[ 0., 0., 0.],
Chris@87 3370 [ 1., 1., 1.]])
Chris@87 3371 >>> xv, yv = meshgrid(x, y, sparse=True) # make sparse output arrays
Chris@87 3372 >>> xv
Chris@87 3373 array([[ 0. , 0.5, 1. ]])
Chris@87 3374 >>> yv
Chris@87 3375 array([[ 0.],
Chris@87 3376 [ 1.]])
Chris@87 3377
Chris@87 3378 `meshgrid` is very useful to evaluate functions on a grid.
Chris@87 3379
Chris@87 3380 >>> x = np.arange(-5, 5, 0.1)
Chris@87 3381 >>> y = np.arange(-5, 5, 0.1)
Chris@87 3382 >>> xx, yy = meshgrid(x, y, sparse=True)
Chris@87 3383 >>> z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
Chris@87 3384 >>> h = plt.contourf(x,y,z)
Chris@87 3385
Chris@87 3386 """
Chris@87 3387 ndim = len(xi)
Chris@87 3388
Chris@87 3389 copy_ = kwargs.pop('copy', True)
Chris@87 3390 sparse = kwargs.pop('sparse', False)
Chris@87 3391 indexing = kwargs.pop('indexing', 'xy')
Chris@87 3392
Chris@87 3393 if kwargs:
Chris@87 3394 raise TypeError("meshgrid() got an unexpected keyword argument '%s'"
Chris@87 3395 % (list(kwargs)[0],))
Chris@87 3396
Chris@87 3397 if indexing not in ['xy', 'ij']:
Chris@87 3398 raise ValueError(
Chris@87 3399 "Valid values for `indexing` are 'xy' and 'ij'.")
Chris@87 3400
Chris@87 3401 s0 = (1,) * ndim
Chris@87 3402 output = [np.asanyarray(x).reshape(s0[:i] + (-1,) + s0[i + 1::])
Chris@87 3403 for i, x in enumerate(xi)]
Chris@87 3404
Chris@87 3405 shape = [x.size for x in output]
Chris@87 3406
Chris@87 3407 if indexing == 'xy' and ndim > 1:
Chris@87 3408 # switch first and second axis
Chris@87 3409 output[0].shape = (1, -1) + (1,)*(ndim - 2)
Chris@87 3410 output[1].shape = (-1, 1) + (1,)*(ndim - 2)
Chris@87 3411 shape[0], shape[1] = shape[1], shape[0]
Chris@87 3412
Chris@87 3413 if sparse:
Chris@87 3414 if copy_:
Chris@87 3415 return [x.copy() for x in output]
Chris@87 3416 else:
Chris@87 3417 return output
Chris@87 3418 else:
Chris@87 3419 # Return the full N-D matrix (not only the 1-D vector)
Chris@87 3420 if copy_:
Chris@87 3421 mult_fact = np.ones(shape, dtype=int)
Chris@87 3422 return [x * mult_fact for x in output]
Chris@87 3423 else:
Chris@87 3424 return np.broadcast_arrays(*output)
Chris@87 3425
Chris@87 3426
Chris@87 3427 def delete(arr, obj, axis=None):
Chris@87 3428 """
Chris@87 3429 Return a new array with sub-arrays along an axis deleted. For a one
Chris@87 3430 dimensional array, this returns those entries not returned by
Chris@87 3431 `arr[obj]`.
Chris@87 3432
Chris@87 3433 Parameters
Chris@87 3434 ----------
Chris@87 3435 arr : array_like
Chris@87 3436 Input array.
Chris@87 3437 obj : slice, int or array of ints
Chris@87 3438 Indicate which sub-arrays to remove.
Chris@87 3439 axis : int, optional
Chris@87 3440 The axis along which to delete the subarray defined by `obj`.
Chris@87 3441 If `axis` is None, `obj` is applied to the flattened array.
Chris@87 3442
Chris@87 3443 Returns
Chris@87 3444 -------
Chris@87 3445 out : ndarray
Chris@87 3446 A copy of `arr` with the elements specified by `obj` removed. Note
Chris@87 3447 that `delete` does not occur in-place. If `axis` is None, `out` is
Chris@87 3448 a flattened array.
Chris@87 3449
Chris@87 3450 See Also
Chris@87 3451 --------
Chris@87 3452 insert : Insert elements into an array.
Chris@87 3453 append : Append elements at the end of an array.
Chris@87 3454
Chris@87 3455 Notes
Chris@87 3456 -----
Chris@87 3457 Often it is preferable to use a boolean mask. For example:
Chris@87 3458
Chris@87 3459 >>> mask = np.ones(len(arr), dtype=bool)
Chris@87 3460 >>> mask[[0,2,4]] = False
Chris@87 3461 >>> result = arr[mask,...]
Chris@87 3462
Chris@87 3463 Is equivalent to `np.delete(arr, [0,2,4], axis=0)`, but allows further
Chris@87 3464 use of `mask`.
Chris@87 3465
Chris@87 3466 Examples
Chris@87 3467 --------
Chris@87 3468 >>> arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
Chris@87 3469 >>> arr
Chris@87 3470 array([[ 1, 2, 3, 4],
Chris@87 3471 [ 5, 6, 7, 8],
Chris@87 3472 [ 9, 10, 11, 12]])
Chris@87 3473 >>> np.delete(arr, 1, 0)
Chris@87 3474 array([[ 1, 2, 3, 4],
Chris@87 3475 [ 9, 10, 11, 12]])
Chris@87 3476
Chris@87 3477 >>> np.delete(arr, np.s_[::2], 1)
Chris@87 3478 array([[ 2, 4],
Chris@87 3479 [ 6, 8],
Chris@87 3480 [10, 12]])
Chris@87 3481 >>> np.delete(arr, [1,3,5], None)
Chris@87 3482 array([ 1, 3, 5, 7, 8, 9, 10, 11, 12])
Chris@87 3483
Chris@87 3484 """
Chris@87 3485 wrap = None
Chris@87 3486 if type(arr) is not ndarray:
Chris@87 3487 try:
Chris@87 3488 wrap = arr.__array_wrap__
Chris@87 3489 except AttributeError:
Chris@87 3490 pass
Chris@87 3491
Chris@87 3492 arr = asarray(arr)
Chris@87 3493 ndim = arr.ndim
Chris@87 3494 if axis is None:
Chris@87 3495 if ndim != 1:
Chris@87 3496 arr = arr.ravel()
Chris@87 3497 ndim = arr.ndim
Chris@87 3498 axis = ndim - 1
Chris@87 3499 if ndim == 0:
Chris@87 3500 warnings.warn(
Chris@87 3501 "in the future the special handling of scalars will be removed "
Chris@87 3502 "from delete and raise an error", DeprecationWarning)
Chris@87 3503 if wrap:
Chris@87 3504 return wrap(arr)
Chris@87 3505 else:
Chris@87 3506 return arr.copy()
Chris@87 3507
Chris@87 3508 slobj = [slice(None)]*ndim
Chris@87 3509 N = arr.shape[axis]
Chris@87 3510 newshape = list(arr.shape)
Chris@87 3511
Chris@87 3512 if isinstance(obj, slice):
Chris@87 3513 start, stop, step = obj.indices(N)
Chris@87 3514 xr = range(start, stop, step)
Chris@87 3515 numtodel = len(xr)
Chris@87 3516
Chris@87 3517 if numtodel <= 0:
Chris@87 3518 if wrap:
Chris@87 3519 return wrap(arr.copy())
Chris@87 3520 else:
Chris@87 3521 return arr.copy()
Chris@87 3522
Chris@87 3523 # Invert if step is negative:
Chris@87 3524 if step < 0:
Chris@87 3525 step = -step
Chris@87 3526 start = xr[-1]
Chris@87 3527 stop = xr[0] + 1
Chris@87 3528
Chris@87 3529 newshape[axis] -= numtodel
Chris@87 3530 new = empty(newshape, arr.dtype, arr.flags.fnc)
Chris@87 3531 # copy initial chunk
Chris@87 3532 if start == 0:
Chris@87 3533 pass
Chris@87 3534 else:
Chris@87 3535 slobj[axis] = slice(None, start)
Chris@87 3536 new[slobj] = arr[slobj]
Chris@87 3537 # copy end chunck
Chris@87 3538 if stop == N:
Chris@87 3539 pass
Chris@87 3540 else:
Chris@87 3541 slobj[axis] = slice(stop-numtodel, None)
Chris@87 3542 slobj2 = [slice(None)]*ndim
Chris@87 3543 slobj2[axis] = slice(stop, None)
Chris@87 3544 new[slobj] = arr[slobj2]
Chris@87 3545 # copy middle pieces
Chris@87 3546 if step == 1:
Chris@87 3547 pass
Chris@87 3548 else: # use array indexing.
Chris@87 3549 keep = ones(stop-start, dtype=bool)
Chris@87 3550 keep[:stop-start:step] = False
Chris@87 3551 slobj[axis] = slice(start, stop-numtodel)
Chris@87 3552 slobj2 = [slice(None)]*ndim
Chris@87 3553 slobj2[axis] = slice(start, stop)
Chris@87 3554 arr = arr[slobj2]
Chris@87 3555 slobj2[axis] = keep
Chris@87 3556 new[slobj] = arr[slobj2]
Chris@87 3557 if wrap:
Chris@87 3558 return wrap(new)
Chris@87 3559 else:
Chris@87 3560 return new
Chris@87 3561
Chris@87 3562 _obj = obj
Chris@87 3563 obj = np.asarray(obj)
Chris@87 3564 # After removing the special handling of booleans and out of
Chris@87 3565 # bounds values, the conversion to the array can be removed.
Chris@87 3566 if obj.dtype == bool:
Chris@87 3567 warnings.warn(
Chris@87 3568 "in the future insert will treat boolean arrays and array-likes "
Chris@87 3569 "as boolean index instead of casting it to integer", FutureWarning)
Chris@87 3570 obj = obj.astype(intp)
Chris@87 3571 if isinstance(_obj, (int, long, integer)):
Chris@87 3572 # optimization for a single value
Chris@87 3573 obj = obj.item()
Chris@87 3574 if (obj < -N or obj >= N):
Chris@87 3575 raise IndexError(
Chris@87 3576 "index %i is out of bounds for axis %i with "
Chris@87 3577 "size %i" % (obj, axis, N))
Chris@87 3578 if (obj < 0):
Chris@87 3579 obj += N
Chris@87 3580 newshape[axis] -= 1
Chris@87 3581 new = empty(newshape, arr.dtype, arr.flags.fnc)
Chris@87 3582 slobj[axis] = slice(None, obj)
Chris@87 3583 new[slobj] = arr[slobj]
Chris@87 3584 slobj[axis] = slice(obj, None)
Chris@87 3585 slobj2 = [slice(None)]*ndim
Chris@87 3586 slobj2[axis] = slice(obj+1, None)
Chris@87 3587 new[slobj] = arr[slobj2]
Chris@87 3588 else:
Chris@87 3589 if obj.size == 0 and not isinstance(_obj, np.ndarray):
Chris@87 3590 obj = obj.astype(intp)
Chris@87 3591 if not np.can_cast(obj, intp, 'same_kind'):
Chris@87 3592 # obj.size = 1 special case always failed and would just
Chris@87 3593 # give superfluous warnings.
Chris@87 3594 warnings.warn(
Chris@87 3595 "using a non-integer array as obj in delete will result in an "
Chris@87 3596 "error in the future", DeprecationWarning)
Chris@87 3597 obj = obj.astype(intp)
Chris@87 3598 keep = ones(N, dtype=bool)
Chris@87 3599
Chris@87 3600 # Test if there are out of bound indices, this is deprecated
Chris@87 3601 inside_bounds = (obj < N) & (obj >= -N)
Chris@87 3602 if not inside_bounds.all():
Chris@87 3603 warnings.warn(
Chris@87 3604 "in the future out of bounds indices will raise an error "
Chris@87 3605 "instead of being ignored by `numpy.delete`.",
Chris@87 3606 DeprecationWarning)
Chris@87 3607 obj = obj[inside_bounds]
Chris@87 3608 positive_indices = obj >= 0
Chris@87 3609 if not positive_indices.all():
Chris@87 3610 warnings.warn(
Chris@87 3611 "in the future negative indices will not be ignored by "
Chris@87 3612 "`numpy.delete`.", FutureWarning)
Chris@87 3613 obj = obj[positive_indices]
Chris@87 3614
Chris@87 3615 keep[obj, ] = False
Chris@87 3616 slobj[axis] = keep
Chris@87 3617 new = arr[slobj]
Chris@87 3618
Chris@87 3619 if wrap:
Chris@87 3620 return wrap(new)
Chris@87 3621 else:
Chris@87 3622 return new
Chris@87 3623
Chris@87 3624
Chris@87 3625 def insert(arr, obj, values, axis=None):
Chris@87 3626 """
Chris@87 3627 Insert values along the given axis before the given indices.
Chris@87 3628
Chris@87 3629 Parameters
Chris@87 3630 ----------
Chris@87 3631 arr : array_like
Chris@87 3632 Input array.
Chris@87 3633 obj : int, slice or sequence of ints
Chris@87 3634 Object that defines the index or indices before which `values` is
Chris@87 3635 inserted.
Chris@87 3636
Chris@87 3637 .. versionadded:: 1.8.0
Chris@87 3638
Chris@87 3639 Support for multiple insertions when `obj` is a single scalar or a
Chris@87 3640 sequence with one element (similar to calling insert multiple
Chris@87 3641 times).
Chris@87 3642 values : array_like
Chris@87 3643 Values to insert into `arr`. If the type of `values` is different
Chris@87 3644 from that of `arr`, `values` is converted to the type of `arr`.
Chris@87 3645 `values` should be shaped so that ``arr[...,obj,...] = values``
Chris@87 3646 is legal.
Chris@87 3647 axis : int, optional
Chris@87 3648 Axis along which to insert `values`. If `axis` is None then `arr`
Chris@87 3649 is flattened first.
Chris@87 3650
Chris@87 3651 Returns
Chris@87 3652 -------
Chris@87 3653 out : ndarray
Chris@87 3654 A copy of `arr` with `values` inserted. Note that `insert`
Chris@87 3655 does not occur in-place: a new array is returned. If
Chris@87 3656 `axis` is None, `out` is a flattened array.
Chris@87 3657
Chris@87 3658 See Also
Chris@87 3659 --------
Chris@87 3660 append : Append elements at the end of an array.
Chris@87 3661 concatenate : Join a sequence of arrays together.
Chris@87 3662 delete : Delete elements from an array.
Chris@87 3663
Chris@87 3664 Notes
Chris@87 3665 -----
Chris@87 3666 Note that for higher dimensional inserts `obj=0` behaves very different
Chris@87 3667 from `obj=[0]` just like `arr[:,0,:] = values` is different from
Chris@87 3668 `arr[:,[0],:] = values`.
Chris@87 3669
Chris@87 3670 Examples
Chris@87 3671 --------
Chris@87 3672 >>> a = np.array([[1, 1], [2, 2], [3, 3]])
Chris@87 3673 >>> a
Chris@87 3674 array([[1, 1],
Chris@87 3675 [2, 2],
Chris@87 3676 [3, 3]])
Chris@87 3677 >>> np.insert(a, 1, 5)
Chris@87 3678 array([1, 5, 1, 2, 2, 3, 3])
Chris@87 3679 >>> np.insert(a, 1, 5, axis=1)
Chris@87 3680 array([[1, 5, 1],
Chris@87 3681 [2, 5, 2],
Chris@87 3682 [3, 5, 3]])
Chris@87 3683
Chris@87 3684 Difference between sequence and scalars:
Chris@87 3685 >>> np.insert(a, [1], [[1],[2],[3]], axis=1)
Chris@87 3686 array([[1, 1, 1],
Chris@87 3687 [2, 2, 2],
Chris@87 3688 [3, 3, 3]])
Chris@87 3689 >>> np.array_equal(np.insert(a, 1, [1, 2, 3], axis=1),
Chris@87 3690 ... np.insert(a, [1], [[1],[2],[3]], axis=1))
Chris@87 3691 True
Chris@87 3692
Chris@87 3693 >>> b = a.flatten()
Chris@87 3694 >>> b
Chris@87 3695 array([1, 1, 2, 2, 3, 3])
Chris@87 3696 >>> np.insert(b, [2, 2], [5, 6])
Chris@87 3697 array([1, 1, 5, 6, 2, 2, 3, 3])
Chris@87 3698
Chris@87 3699 >>> np.insert(b, slice(2, 4), [5, 6])
Chris@87 3700 array([1, 1, 5, 2, 6, 2, 3, 3])
Chris@87 3701
Chris@87 3702 >>> np.insert(b, [2, 2], [7.13, False]) # type casting
Chris@87 3703 array([1, 1, 7, 0, 2, 2, 3, 3])
Chris@87 3704
Chris@87 3705 >>> x = np.arange(8).reshape(2, 4)
Chris@87 3706 >>> idx = (1, 3)
Chris@87 3707 >>> np.insert(x, idx, 999, axis=1)
Chris@87 3708 array([[ 0, 999, 1, 2, 999, 3],
Chris@87 3709 [ 4, 999, 5, 6, 999, 7]])
Chris@87 3710
Chris@87 3711 """
Chris@87 3712 wrap = None
Chris@87 3713 if type(arr) is not ndarray:
Chris@87 3714 try:
Chris@87 3715 wrap = arr.__array_wrap__
Chris@87 3716 except AttributeError:
Chris@87 3717 pass
Chris@87 3718
Chris@87 3719 arr = asarray(arr)
Chris@87 3720 ndim = arr.ndim
Chris@87 3721 if axis is None:
Chris@87 3722 if ndim != 1:
Chris@87 3723 arr = arr.ravel()
Chris@87 3724 ndim = arr.ndim
Chris@87 3725 axis = ndim - 1
Chris@87 3726 else:
Chris@87 3727 if ndim > 0 and (axis < -ndim or axis >= ndim):
Chris@87 3728 raise IndexError(
Chris@87 3729 "axis %i is out of bounds for an array of "
Chris@87 3730 "dimension %i" % (axis, ndim))
Chris@87 3731 if (axis < 0):
Chris@87 3732 axis += ndim
Chris@87 3733 if (ndim == 0):
Chris@87 3734 warnings.warn(
Chris@87 3735 "in the future the special handling of scalars will be removed "
Chris@87 3736 "from insert and raise an error", DeprecationWarning)
Chris@87 3737 arr = arr.copy()
Chris@87 3738 arr[...] = values
Chris@87 3739 if wrap:
Chris@87 3740 return wrap(arr)
Chris@87 3741 else:
Chris@87 3742 return arr
Chris@87 3743 slobj = [slice(None)]*ndim
Chris@87 3744 N = arr.shape[axis]
Chris@87 3745 newshape = list(arr.shape)
Chris@87 3746
Chris@87 3747 if isinstance(obj, slice):
Chris@87 3748 # turn it into a range object
Chris@87 3749 indices = arange(*obj.indices(N), **{'dtype': intp})
Chris@87 3750 else:
Chris@87 3751 # need to copy obj, because indices will be changed in-place
Chris@87 3752 indices = np.array(obj)
Chris@87 3753 if indices.dtype == bool:
Chris@87 3754 # See also delete
Chris@87 3755 warnings.warn(
Chris@87 3756 "in the future insert will treat boolean arrays and "
Chris@87 3757 "array-likes as a boolean index instead of casting it to "
Chris@87 3758 "integer", FutureWarning)
Chris@87 3759 indices = indices.astype(intp)
Chris@87 3760 # Code after warning period:
Chris@87 3761 #if obj.ndim != 1:
Chris@87 3762 # raise ValueError('boolean array argument obj to insert '
Chris@87 3763 # 'must be one dimensional')
Chris@87 3764 #indices = np.flatnonzero(obj)
Chris@87 3765 elif indices.ndim > 1:
Chris@87 3766 raise ValueError(
Chris@87 3767 "index array argument obj to insert must be one dimensional "
Chris@87 3768 "or scalar")
Chris@87 3769 if indices.size == 1:
Chris@87 3770 index = indices.item()
Chris@87 3771 if index < -N or index > N:
Chris@87 3772 raise IndexError(
Chris@87 3773 "index %i is out of bounds for axis %i with "
Chris@87 3774 "size %i" % (obj, axis, N))
Chris@87 3775 if (index < 0):
Chris@87 3776 index += N
Chris@87 3777
Chris@87 3778 # There are some object array corner cases here, but we cannot avoid
Chris@87 3779 # that:
Chris@87 3780 values = array(values, copy=False, ndmin=arr.ndim, dtype=arr.dtype)
Chris@87 3781 if indices.ndim == 0:
Chris@87 3782 # broadcasting is very different here, since a[:,0,:] = ... behaves
Chris@87 3783 # very different from a[:,[0],:] = ...! This changes values so that
Chris@87 3784 # it works likes the second case. (here a[:,0:1,:])
Chris@87 3785 values = np.rollaxis(values, 0, (axis % values.ndim) + 1)
Chris@87 3786 numnew = values.shape[axis]
Chris@87 3787 newshape[axis] += numnew
Chris@87 3788 new = empty(newshape, arr.dtype, arr.flags.fnc)
Chris@87 3789 slobj[axis] = slice(None, index)
Chris@87 3790 new[slobj] = arr[slobj]
Chris@87 3791 slobj[axis] = slice(index, index+numnew)
Chris@87 3792 new[slobj] = values
Chris@87 3793 slobj[axis] = slice(index+numnew, None)
Chris@87 3794 slobj2 = [slice(None)] * ndim
Chris@87 3795 slobj2[axis] = slice(index, None)
Chris@87 3796 new[slobj] = arr[slobj2]
Chris@87 3797 if wrap:
Chris@87 3798 return wrap(new)
Chris@87 3799 return new
Chris@87 3800 elif indices.size == 0 and not isinstance(obj, np.ndarray):
Chris@87 3801 # Can safely cast the empty list to intp
Chris@87 3802 indices = indices.astype(intp)
Chris@87 3803
Chris@87 3804 if not np.can_cast(indices, intp, 'same_kind'):
Chris@87 3805 warnings.warn(
Chris@87 3806 "using a non-integer array as obj in insert will result in an "
Chris@87 3807 "error in the future", DeprecationWarning)
Chris@87 3808 indices = indices.astype(intp)
Chris@87 3809
Chris@87 3810 indices[indices < 0] += N
Chris@87 3811
Chris@87 3812 numnew = len(indices)
Chris@87 3813 order = indices.argsort(kind='mergesort') # stable sort
Chris@87 3814 indices[order] += np.arange(numnew)
Chris@87 3815
Chris@87 3816 newshape[axis] += numnew
Chris@87 3817 old_mask = ones(newshape[axis], dtype=bool)
Chris@87 3818 old_mask[indices] = False
Chris@87 3819
Chris@87 3820 new = empty(newshape, arr.dtype, arr.flags.fnc)
Chris@87 3821 slobj2 = [slice(None)]*ndim
Chris@87 3822 slobj[axis] = indices
Chris@87 3823 slobj2[axis] = old_mask
Chris@87 3824 new[slobj] = values
Chris@87 3825 new[slobj2] = arr
Chris@87 3826
Chris@87 3827 if wrap:
Chris@87 3828 return wrap(new)
Chris@87 3829 return new
Chris@87 3830
Chris@87 3831
Chris@87 3832 def append(arr, values, axis=None):
Chris@87 3833 """
Chris@87 3834 Append values to the end of an array.
Chris@87 3835
Chris@87 3836 Parameters
Chris@87 3837 ----------
Chris@87 3838 arr : array_like
Chris@87 3839 Values are appended to a copy of this array.
Chris@87 3840 values : array_like
Chris@87 3841 These values are appended to a copy of `arr`. It must be of the
Chris@87 3842 correct shape (the same shape as `arr`, excluding `axis`). If
Chris@87 3843 `axis` is not specified, `values` can be any shape and will be
Chris@87 3844 flattened before use.
Chris@87 3845 axis : int, optional
Chris@87 3846 The axis along which `values` are appended. If `axis` is not
Chris@87 3847 given, both `arr` and `values` are flattened before use.
Chris@87 3848
Chris@87 3849 Returns
Chris@87 3850 -------
Chris@87 3851 append : ndarray
Chris@87 3852 A copy of `arr` with `values` appended to `axis`. Note that
Chris@87 3853 `append` does not occur in-place: a new array is allocated and
Chris@87 3854 filled. If `axis` is None, `out` is a flattened array.
Chris@87 3855
Chris@87 3856 See Also
Chris@87 3857 --------
Chris@87 3858 insert : Insert elements into an array.
Chris@87 3859 delete : Delete elements from an array.
Chris@87 3860
Chris@87 3861 Examples
Chris@87 3862 --------
Chris@87 3863 >>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])
Chris@87 3864 array([1, 2, 3, 4, 5, 6, 7, 8, 9])
Chris@87 3865
Chris@87 3866 When `axis` is specified, `values` must have the correct shape.
Chris@87 3867
Chris@87 3868 >>> np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0)
Chris@87 3869 array([[1, 2, 3],
Chris@87 3870 [4, 5, 6],
Chris@87 3871 [7, 8, 9]])
Chris@87 3872 >>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0)
Chris@87 3873 Traceback (most recent call last):
Chris@87 3874 ...
Chris@87 3875 ValueError: arrays must have same number of dimensions
Chris@87 3876
Chris@87 3877 """
Chris@87 3878 arr = asanyarray(arr)
Chris@87 3879 if axis is None:
Chris@87 3880 if arr.ndim != 1:
Chris@87 3881 arr = arr.ravel()
Chris@87 3882 values = ravel(values)
Chris@87 3883 axis = arr.ndim-1
Chris@87 3884 return concatenate((arr, values), axis=axis)