annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/lib/shape_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
Chris@87 5 import numpy.core.numeric as _nx
Chris@87 6 from numpy.core.numeric import (
Chris@87 7 asarray, zeros, outer, concatenate, isscalar, array, asanyarray
Chris@87 8 )
Chris@87 9 from numpy.core.fromnumeric import product, reshape
Chris@87 10 from numpy.core import vstack, atleast_3d
Chris@87 11
Chris@87 12
Chris@87 13 __all__ = [
Chris@87 14 'column_stack', 'row_stack', 'dstack', 'array_split', 'split',
Chris@87 15 'hsplit', 'vsplit', 'dsplit', 'apply_over_axes', 'expand_dims',
Chris@87 16 'apply_along_axis', 'kron', 'tile', 'get_array_wrap'
Chris@87 17 ]
Chris@87 18
Chris@87 19
Chris@87 20 def apply_along_axis(func1d, axis, arr, *args, **kwargs):
Chris@87 21 """
Chris@87 22 Apply a function to 1-D slices along the given axis.
Chris@87 23
Chris@87 24 Execute `func1d(a, *args)` where `func1d` operates on 1-D arrays and `a`
Chris@87 25 is a 1-D slice of `arr` along `axis`.
Chris@87 26
Chris@87 27 Parameters
Chris@87 28 ----------
Chris@87 29 func1d : function
Chris@87 30 This function should accept 1-D arrays. It is applied to 1-D
Chris@87 31 slices of `arr` along the specified axis.
Chris@87 32 axis : integer
Chris@87 33 Axis along which `arr` is sliced.
Chris@87 34 arr : ndarray
Chris@87 35 Input array.
Chris@87 36 args : any
Chris@87 37 Additional arguments to `func1d`.
Chris@87 38 kwargs: any
Chris@87 39 Additional named arguments to `func1d`.
Chris@87 40
Chris@87 41 .. versionadded:: 1.9.0
Chris@87 42
Chris@87 43
Chris@87 44 Returns
Chris@87 45 -------
Chris@87 46 apply_along_axis : ndarray
Chris@87 47 The output array. The shape of `outarr` is identical to the shape of
Chris@87 48 `arr`, except along the `axis` dimension, where the length of `outarr`
Chris@87 49 is equal to the size of the return value of `func1d`. If `func1d`
Chris@87 50 returns a scalar `outarr` will have one fewer dimensions than `arr`.
Chris@87 51
Chris@87 52 See Also
Chris@87 53 --------
Chris@87 54 apply_over_axes : Apply a function repeatedly over multiple axes.
Chris@87 55
Chris@87 56 Examples
Chris@87 57 --------
Chris@87 58 >>> def my_func(a):
Chris@87 59 ... \"\"\"Average first and last element of a 1-D array\"\"\"
Chris@87 60 ... return (a[0] + a[-1]) * 0.5
Chris@87 61 >>> b = np.array([[1,2,3], [4,5,6], [7,8,9]])
Chris@87 62 >>> np.apply_along_axis(my_func, 0, b)
Chris@87 63 array([ 4., 5., 6.])
Chris@87 64 >>> np.apply_along_axis(my_func, 1, b)
Chris@87 65 array([ 2., 5., 8.])
Chris@87 66
Chris@87 67 For a function that doesn't return a scalar, the number of dimensions in
Chris@87 68 `outarr` is the same as `arr`.
Chris@87 69
Chris@87 70 >>> b = np.array([[8,1,7], [4,3,9], [5,2,6]])
Chris@87 71 >>> np.apply_along_axis(sorted, 1, b)
Chris@87 72 array([[1, 7, 8],
Chris@87 73 [3, 4, 9],
Chris@87 74 [2, 5, 6]])
Chris@87 75
Chris@87 76 """
Chris@87 77 arr = asarray(arr)
Chris@87 78 nd = arr.ndim
Chris@87 79 if axis < 0:
Chris@87 80 axis += nd
Chris@87 81 if (axis >= nd):
Chris@87 82 raise ValueError("axis must be less than arr.ndim; axis=%d, rank=%d."
Chris@87 83 % (axis, nd))
Chris@87 84 ind = [0]*(nd-1)
Chris@87 85 i = zeros(nd, 'O')
Chris@87 86 indlist = list(range(nd))
Chris@87 87 indlist.remove(axis)
Chris@87 88 i[axis] = slice(None, None)
Chris@87 89 outshape = asarray(arr.shape).take(indlist)
Chris@87 90 i.put(indlist, ind)
Chris@87 91 res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
Chris@87 92 # if res is a number, then we have a smaller output array
Chris@87 93 if isscalar(res):
Chris@87 94 outarr = zeros(outshape, asarray(res).dtype)
Chris@87 95 outarr[tuple(ind)] = res
Chris@87 96 Ntot = product(outshape)
Chris@87 97 k = 1
Chris@87 98 while k < Ntot:
Chris@87 99 # increment the index
Chris@87 100 ind[-1] += 1
Chris@87 101 n = -1
Chris@87 102 while (ind[n] >= outshape[n]) and (n > (1-nd)):
Chris@87 103 ind[n-1] += 1
Chris@87 104 ind[n] = 0
Chris@87 105 n -= 1
Chris@87 106 i.put(indlist, ind)
Chris@87 107 res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
Chris@87 108 outarr[tuple(ind)] = res
Chris@87 109 k += 1
Chris@87 110 return outarr
Chris@87 111 else:
Chris@87 112 Ntot = product(outshape)
Chris@87 113 holdshape = outshape
Chris@87 114 outshape = list(arr.shape)
Chris@87 115 outshape[axis] = len(res)
Chris@87 116 outarr = zeros(outshape, asarray(res).dtype)
Chris@87 117 outarr[tuple(i.tolist())] = res
Chris@87 118 k = 1
Chris@87 119 while k < Ntot:
Chris@87 120 # increment the index
Chris@87 121 ind[-1] += 1
Chris@87 122 n = -1
Chris@87 123 while (ind[n] >= holdshape[n]) and (n > (1-nd)):
Chris@87 124 ind[n-1] += 1
Chris@87 125 ind[n] = 0
Chris@87 126 n -= 1
Chris@87 127 i.put(indlist, ind)
Chris@87 128 res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
Chris@87 129 outarr[tuple(i.tolist())] = res
Chris@87 130 k += 1
Chris@87 131 return outarr
Chris@87 132
Chris@87 133
Chris@87 134 def apply_over_axes(func, a, axes):
Chris@87 135 """
Chris@87 136 Apply a function repeatedly over multiple axes.
Chris@87 137
Chris@87 138 `func` is called as `res = func(a, axis)`, where `axis` is the first
Chris@87 139 element of `axes`. The result `res` of the function call must have
Chris@87 140 either the same dimensions as `a` or one less dimension. If `res`
Chris@87 141 has one less dimension than `a`, a dimension is inserted before
Chris@87 142 `axis`. The call to `func` is then repeated for each axis in `axes`,
Chris@87 143 with `res` as the first argument.
Chris@87 144
Chris@87 145 Parameters
Chris@87 146 ----------
Chris@87 147 func : function
Chris@87 148 This function must take two arguments, `func(a, axis)`.
Chris@87 149 a : array_like
Chris@87 150 Input array.
Chris@87 151 axes : array_like
Chris@87 152 Axes over which `func` is applied; the elements must be integers.
Chris@87 153
Chris@87 154 Returns
Chris@87 155 -------
Chris@87 156 apply_over_axis : ndarray
Chris@87 157 The output array. The number of dimensions is the same as `a`,
Chris@87 158 but the shape can be different. This depends on whether `func`
Chris@87 159 changes the shape of its output with respect to its input.
Chris@87 160
Chris@87 161 See Also
Chris@87 162 --------
Chris@87 163 apply_along_axis :
Chris@87 164 Apply a function to 1-D slices of an array along the given axis.
Chris@87 165
Chris@87 166 Notes
Chris@87 167 ------
Chris@87 168 This function is equivalent to tuple axis arguments to reorderable ufuncs
Chris@87 169 with keepdims=True. Tuple axis arguments to ufuncs have been availabe since
Chris@87 170 version 1.7.0.
Chris@87 171
Chris@87 172 Examples
Chris@87 173 --------
Chris@87 174 >>> a = np.arange(24).reshape(2,3,4)
Chris@87 175 >>> a
Chris@87 176 array([[[ 0, 1, 2, 3],
Chris@87 177 [ 4, 5, 6, 7],
Chris@87 178 [ 8, 9, 10, 11]],
Chris@87 179 [[12, 13, 14, 15],
Chris@87 180 [16, 17, 18, 19],
Chris@87 181 [20, 21, 22, 23]]])
Chris@87 182
Chris@87 183 Sum over axes 0 and 2. The result has same number of dimensions
Chris@87 184 as the original array:
Chris@87 185
Chris@87 186 >>> np.apply_over_axes(np.sum, a, [0,2])
Chris@87 187 array([[[ 60],
Chris@87 188 [ 92],
Chris@87 189 [124]]])
Chris@87 190
Chris@87 191 Tuple axis arguments to ufuncs are equivalent:
Chris@87 192
Chris@87 193 >>> np.sum(a, axis=(0,2), keepdims=True)
Chris@87 194 array([[[ 60],
Chris@87 195 [ 92],
Chris@87 196 [124]]])
Chris@87 197
Chris@87 198 """
Chris@87 199 val = asarray(a)
Chris@87 200 N = a.ndim
Chris@87 201 if array(axes).ndim == 0:
Chris@87 202 axes = (axes,)
Chris@87 203 for axis in axes:
Chris@87 204 if axis < 0:
Chris@87 205 axis = N + axis
Chris@87 206 args = (val, axis)
Chris@87 207 res = func(*args)
Chris@87 208 if res.ndim == val.ndim:
Chris@87 209 val = res
Chris@87 210 else:
Chris@87 211 res = expand_dims(res, axis)
Chris@87 212 if res.ndim == val.ndim:
Chris@87 213 val = res
Chris@87 214 else:
Chris@87 215 raise ValueError("function is not returning "
Chris@87 216 "an array of the correct shape")
Chris@87 217 return val
Chris@87 218
Chris@87 219 def expand_dims(a, axis):
Chris@87 220 """
Chris@87 221 Expand the shape of an array.
Chris@87 222
Chris@87 223 Insert a new axis, corresponding to a given position in the array shape.
Chris@87 224
Chris@87 225 Parameters
Chris@87 226 ----------
Chris@87 227 a : array_like
Chris@87 228 Input array.
Chris@87 229 axis : int
Chris@87 230 Position (amongst axes) where new axis is to be inserted.
Chris@87 231
Chris@87 232 Returns
Chris@87 233 -------
Chris@87 234 res : ndarray
Chris@87 235 Output array. The number of dimensions is one greater than that of
Chris@87 236 the input array.
Chris@87 237
Chris@87 238 See Also
Chris@87 239 --------
Chris@87 240 doc.indexing, atleast_1d, atleast_2d, atleast_3d
Chris@87 241
Chris@87 242 Examples
Chris@87 243 --------
Chris@87 244 >>> x = np.array([1,2])
Chris@87 245 >>> x.shape
Chris@87 246 (2,)
Chris@87 247
Chris@87 248 The following is equivalent to ``x[np.newaxis,:]`` or ``x[np.newaxis]``:
Chris@87 249
Chris@87 250 >>> y = np.expand_dims(x, axis=0)
Chris@87 251 >>> y
Chris@87 252 array([[1, 2]])
Chris@87 253 >>> y.shape
Chris@87 254 (1, 2)
Chris@87 255
Chris@87 256 >>> y = np.expand_dims(x, axis=1) # Equivalent to x[:,newaxis]
Chris@87 257 >>> y
Chris@87 258 array([[1],
Chris@87 259 [2]])
Chris@87 260 >>> y.shape
Chris@87 261 (2, 1)
Chris@87 262
Chris@87 263 Note that some examples may use ``None`` instead of ``np.newaxis``. These
Chris@87 264 are the same objects:
Chris@87 265
Chris@87 266 >>> np.newaxis is None
Chris@87 267 True
Chris@87 268
Chris@87 269 """
Chris@87 270 a = asarray(a)
Chris@87 271 shape = a.shape
Chris@87 272 if axis < 0:
Chris@87 273 axis = axis + len(shape) + 1
Chris@87 274 return a.reshape(shape[:axis] + (1,) + shape[axis:])
Chris@87 275
Chris@87 276 row_stack = vstack
Chris@87 277
Chris@87 278 def column_stack(tup):
Chris@87 279 """
Chris@87 280 Stack 1-D arrays as columns into a 2-D array.
Chris@87 281
Chris@87 282 Take a sequence of 1-D arrays and stack them as columns
Chris@87 283 to make a single 2-D array. 2-D arrays are stacked as-is,
Chris@87 284 just like with `hstack`. 1-D arrays are turned into 2-D columns
Chris@87 285 first.
Chris@87 286
Chris@87 287 Parameters
Chris@87 288 ----------
Chris@87 289 tup : sequence of 1-D or 2-D arrays.
Chris@87 290 Arrays to stack. All of them must have the same first dimension.
Chris@87 291
Chris@87 292 Returns
Chris@87 293 -------
Chris@87 294 stacked : 2-D array
Chris@87 295 The array formed by stacking the given arrays.
Chris@87 296
Chris@87 297 See Also
Chris@87 298 --------
Chris@87 299 hstack, vstack, concatenate
Chris@87 300
Chris@87 301 Examples
Chris@87 302 --------
Chris@87 303 >>> a = np.array((1,2,3))
Chris@87 304 >>> b = np.array((2,3,4))
Chris@87 305 >>> np.column_stack((a,b))
Chris@87 306 array([[1, 2],
Chris@87 307 [2, 3],
Chris@87 308 [3, 4]])
Chris@87 309
Chris@87 310 """
Chris@87 311 arrays = []
Chris@87 312 for v in tup:
Chris@87 313 arr = array(v, copy=False, subok=True)
Chris@87 314 if arr.ndim < 2:
Chris@87 315 arr = array(arr, copy=False, subok=True, ndmin=2).T
Chris@87 316 arrays.append(arr)
Chris@87 317 return _nx.concatenate(arrays, 1)
Chris@87 318
Chris@87 319 def dstack(tup):
Chris@87 320 """
Chris@87 321 Stack arrays in sequence depth wise (along third axis).
Chris@87 322
Chris@87 323 Takes a sequence of arrays and stack them along the third axis
Chris@87 324 to make a single array. Rebuilds arrays divided by `dsplit`.
Chris@87 325 This is a simple way to stack 2D arrays (images) into a single
Chris@87 326 3D array for processing.
Chris@87 327
Chris@87 328 Parameters
Chris@87 329 ----------
Chris@87 330 tup : sequence of arrays
Chris@87 331 Arrays to stack. All of them must have the same shape along all
Chris@87 332 but the third axis.
Chris@87 333
Chris@87 334 Returns
Chris@87 335 -------
Chris@87 336 stacked : ndarray
Chris@87 337 The array formed by stacking the given arrays.
Chris@87 338
Chris@87 339 See Also
Chris@87 340 --------
Chris@87 341 vstack : Stack along first axis.
Chris@87 342 hstack : Stack along second axis.
Chris@87 343 concatenate : Join arrays.
Chris@87 344 dsplit : Split array along third axis.
Chris@87 345
Chris@87 346 Notes
Chris@87 347 -----
Chris@87 348 Equivalent to ``np.concatenate(tup, axis=2)``.
Chris@87 349
Chris@87 350 Examples
Chris@87 351 --------
Chris@87 352 >>> a = np.array((1,2,3))
Chris@87 353 >>> b = np.array((2,3,4))
Chris@87 354 >>> np.dstack((a,b))
Chris@87 355 array([[[1, 2],
Chris@87 356 [2, 3],
Chris@87 357 [3, 4]]])
Chris@87 358
Chris@87 359 >>> a = np.array([[1],[2],[3]])
Chris@87 360 >>> b = np.array([[2],[3],[4]])
Chris@87 361 >>> np.dstack((a,b))
Chris@87 362 array([[[1, 2]],
Chris@87 363 [[2, 3]],
Chris@87 364 [[3, 4]]])
Chris@87 365
Chris@87 366 """
Chris@87 367 return _nx.concatenate([atleast_3d(_m) for _m in tup], 2)
Chris@87 368
Chris@87 369 def _replace_zero_by_x_arrays(sub_arys):
Chris@87 370 for i in range(len(sub_arys)):
Chris@87 371 if len(_nx.shape(sub_arys[i])) == 0:
Chris@87 372 sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype)
Chris@87 373 elif _nx.sometrue(_nx.equal(_nx.shape(sub_arys[i]), 0)):
Chris@87 374 sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype)
Chris@87 375 return sub_arys
Chris@87 376
Chris@87 377 def array_split(ary, indices_or_sections, axis=0):
Chris@87 378 """
Chris@87 379 Split an array into multiple sub-arrays.
Chris@87 380
Chris@87 381 Please refer to the ``split`` documentation. The only difference
Chris@87 382 between these functions is that ``array_split`` allows
Chris@87 383 `indices_or_sections` to be an integer that does *not* equally
Chris@87 384 divide the axis.
Chris@87 385
Chris@87 386 See Also
Chris@87 387 --------
Chris@87 388 split : Split array into multiple sub-arrays of equal size.
Chris@87 389
Chris@87 390 Examples
Chris@87 391 --------
Chris@87 392 >>> x = np.arange(8.0)
Chris@87 393 >>> np.array_split(x, 3)
Chris@87 394 [array([ 0., 1., 2.]), array([ 3., 4., 5.]), array([ 6., 7.])]
Chris@87 395
Chris@87 396 """
Chris@87 397 try:
Chris@87 398 Ntotal = ary.shape[axis]
Chris@87 399 except AttributeError:
Chris@87 400 Ntotal = len(ary)
Chris@87 401 try:
Chris@87 402 # handle scalar case.
Chris@87 403 Nsections = len(indices_or_sections) + 1
Chris@87 404 div_points = [0] + list(indices_or_sections) + [Ntotal]
Chris@87 405 except TypeError:
Chris@87 406 # indices_or_sections is a scalar, not an array.
Chris@87 407 Nsections = int(indices_or_sections)
Chris@87 408 if Nsections <= 0:
Chris@87 409 raise ValueError('number sections must be larger than 0.')
Chris@87 410 Neach_section, extras = divmod(Ntotal, Nsections)
Chris@87 411 section_sizes = ([0] +
Chris@87 412 extras * [Neach_section+1] +
Chris@87 413 (Nsections-extras) * [Neach_section])
Chris@87 414 div_points = _nx.array(section_sizes).cumsum()
Chris@87 415
Chris@87 416 sub_arys = []
Chris@87 417 sary = _nx.swapaxes(ary, axis, 0)
Chris@87 418 for i in range(Nsections):
Chris@87 419 st = div_points[i]
Chris@87 420 end = div_points[i + 1]
Chris@87 421 sub_arys.append(_nx.swapaxes(sary[st:end], axis, 0))
Chris@87 422
Chris@87 423 # This "kludge" was introduced here to replace arrays shaped (0, 10)
Chris@87 424 # or similar with an array shaped (0,).
Chris@87 425 # There seems no need for this, so give a FutureWarning to remove later.
Chris@87 426 if sub_arys[-1].size == 0 and sub_arys[-1].ndim != 1:
Chris@87 427 warnings.warn("in the future np.array_split will retain the shape of "
Chris@87 428 "arrays with a zero size, instead of replacing them by "
Chris@87 429 "`array([])`, which always has a shape of (0,).",
Chris@87 430 FutureWarning)
Chris@87 431 sub_arys = _replace_zero_by_x_arrays(sub_arys)
Chris@87 432
Chris@87 433 return sub_arys
Chris@87 434
Chris@87 435 def split(ary,indices_or_sections,axis=0):
Chris@87 436 """
Chris@87 437 Split an array into multiple sub-arrays.
Chris@87 438
Chris@87 439 Parameters
Chris@87 440 ----------
Chris@87 441 ary : ndarray
Chris@87 442 Array to be divided into sub-arrays.
Chris@87 443 indices_or_sections : int or 1-D array
Chris@87 444 If `indices_or_sections` is an integer, N, the array will be divided
Chris@87 445 into N equal arrays along `axis`. If such a split is not possible,
Chris@87 446 an error is raised.
Chris@87 447
Chris@87 448 If `indices_or_sections` is a 1-D array of sorted integers, the entries
Chris@87 449 indicate where along `axis` the array is split. For example,
Chris@87 450 ``[2, 3]`` would, for ``axis=0``, result in
Chris@87 451
Chris@87 452 - ary[:2]
Chris@87 453 - ary[2:3]
Chris@87 454 - ary[3:]
Chris@87 455
Chris@87 456 If an index exceeds the dimension of the array along `axis`,
Chris@87 457 an empty sub-array is returned correspondingly.
Chris@87 458 axis : int, optional
Chris@87 459 The axis along which to split, default is 0.
Chris@87 460
Chris@87 461 Returns
Chris@87 462 -------
Chris@87 463 sub-arrays : list of ndarrays
Chris@87 464 A list of sub-arrays.
Chris@87 465
Chris@87 466 Raises
Chris@87 467 ------
Chris@87 468 ValueError
Chris@87 469 If `indices_or_sections` is given as an integer, but
Chris@87 470 a split does not result in equal division.
Chris@87 471
Chris@87 472 See Also
Chris@87 473 --------
Chris@87 474 array_split : Split an array into multiple sub-arrays of equal or
Chris@87 475 near-equal size. Does not raise an exception if
Chris@87 476 an equal division cannot be made.
Chris@87 477 hsplit : Split array into multiple sub-arrays horizontally (column-wise).
Chris@87 478 vsplit : Split array into multiple sub-arrays vertically (row wise).
Chris@87 479 dsplit : Split array into multiple sub-arrays along the 3rd axis (depth).
Chris@87 480 concatenate : Join arrays together.
Chris@87 481 hstack : Stack arrays in sequence horizontally (column wise).
Chris@87 482 vstack : Stack arrays in sequence vertically (row wise).
Chris@87 483 dstack : Stack arrays in sequence depth wise (along third dimension).
Chris@87 484
Chris@87 485 Examples
Chris@87 486 --------
Chris@87 487 >>> x = np.arange(9.0)
Chris@87 488 >>> np.split(x, 3)
Chris@87 489 [array([ 0., 1., 2.]), array([ 3., 4., 5.]), array([ 6., 7., 8.])]
Chris@87 490
Chris@87 491 >>> x = np.arange(8.0)
Chris@87 492 >>> np.split(x, [3, 5, 6, 10])
Chris@87 493 [array([ 0., 1., 2.]),
Chris@87 494 array([ 3., 4.]),
Chris@87 495 array([ 5.]),
Chris@87 496 array([ 6., 7.]),
Chris@87 497 array([], dtype=float64)]
Chris@87 498
Chris@87 499 """
Chris@87 500 try:
Chris@87 501 len(indices_or_sections)
Chris@87 502 except TypeError:
Chris@87 503 sections = indices_or_sections
Chris@87 504 N = ary.shape[axis]
Chris@87 505 if N % sections:
Chris@87 506 raise ValueError(
Chris@87 507 'array split does not result in an equal division')
Chris@87 508 res = array_split(ary, indices_or_sections, axis)
Chris@87 509 return res
Chris@87 510
Chris@87 511 def hsplit(ary, indices_or_sections):
Chris@87 512 """
Chris@87 513 Split an array into multiple sub-arrays horizontally (column-wise).
Chris@87 514
Chris@87 515 Please refer to the `split` documentation. `hsplit` is equivalent
Chris@87 516 to `split` with ``axis=1``, the array is always split along the second
Chris@87 517 axis regardless of the array dimension.
Chris@87 518
Chris@87 519 See Also
Chris@87 520 --------
Chris@87 521 split : Split an array into multiple sub-arrays of equal size.
Chris@87 522
Chris@87 523 Examples
Chris@87 524 --------
Chris@87 525 >>> x = np.arange(16.0).reshape(4, 4)
Chris@87 526 >>> x
Chris@87 527 array([[ 0., 1., 2., 3.],
Chris@87 528 [ 4., 5., 6., 7.],
Chris@87 529 [ 8., 9., 10., 11.],
Chris@87 530 [ 12., 13., 14., 15.]])
Chris@87 531 >>> np.hsplit(x, 2)
Chris@87 532 [array([[ 0., 1.],
Chris@87 533 [ 4., 5.],
Chris@87 534 [ 8., 9.],
Chris@87 535 [ 12., 13.]]),
Chris@87 536 array([[ 2., 3.],
Chris@87 537 [ 6., 7.],
Chris@87 538 [ 10., 11.],
Chris@87 539 [ 14., 15.]])]
Chris@87 540 >>> np.hsplit(x, np.array([3, 6]))
Chris@87 541 [array([[ 0., 1., 2.],
Chris@87 542 [ 4., 5., 6.],
Chris@87 543 [ 8., 9., 10.],
Chris@87 544 [ 12., 13., 14.]]),
Chris@87 545 array([[ 3.],
Chris@87 546 [ 7.],
Chris@87 547 [ 11.],
Chris@87 548 [ 15.]]),
Chris@87 549 array([], dtype=float64)]
Chris@87 550
Chris@87 551 With a higher dimensional array the split is still along the second axis.
Chris@87 552
Chris@87 553 >>> x = np.arange(8.0).reshape(2, 2, 2)
Chris@87 554 >>> x
Chris@87 555 array([[[ 0., 1.],
Chris@87 556 [ 2., 3.]],
Chris@87 557 [[ 4., 5.],
Chris@87 558 [ 6., 7.]]])
Chris@87 559 >>> np.hsplit(x, 2)
Chris@87 560 [array([[[ 0., 1.]],
Chris@87 561 [[ 4., 5.]]]),
Chris@87 562 array([[[ 2., 3.]],
Chris@87 563 [[ 6., 7.]]])]
Chris@87 564
Chris@87 565 """
Chris@87 566 if len(_nx.shape(ary)) == 0:
Chris@87 567 raise ValueError('hsplit only works on arrays of 1 or more dimensions')
Chris@87 568 if len(ary.shape) > 1:
Chris@87 569 return split(ary, indices_or_sections, 1)
Chris@87 570 else:
Chris@87 571 return split(ary, indices_or_sections, 0)
Chris@87 572
Chris@87 573 def vsplit(ary, indices_or_sections):
Chris@87 574 """
Chris@87 575 Split an array into multiple sub-arrays vertically (row-wise).
Chris@87 576
Chris@87 577 Please refer to the ``split`` documentation. ``vsplit`` is equivalent
Chris@87 578 to ``split`` with `axis=0` (default), the array is always split along the
Chris@87 579 first axis regardless of the array dimension.
Chris@87 580
Chris@87 581 See Also
Chris@87 582 --------
Chris@87 583 split : Split an array into multiple sub-arrays of equal size.
Chris@87 584
Chris@87 585 Examples
Chris@87 586 --------
Chris@87 587 >>> x = np.arange(16.0).reshape(4, 4)
Chris@87 588 >>> x
Chris@87 589 array([[ 0., 1., 2., 3.],
Chris@87 590 [ 4., 5., 6., 7.],
Chris@87 591 [ 8., 9., 10., 11.],
Chris@87 592 [ 12., 13., 14., 15.]])
Chris@87 593 >>> np.vsplit(x, 2)
Chris@87 594 [array([[ 0., 1., 2., 3.],
Chris@87 595 [ 4., 5., 6., 7.]]),
Chris@87 596 array([[ 8., 9., 10., 11.],
Chris@87 597 [ 12., 13., 14., 15.]])]
Chris@87 598 >>> np.vsplit(x, np.array([3, 6]))
Chris@87 599 [array([[ 0., 1., 2., 3.],
Chris@87 600 [ 4., 5., 6., 7.],
Chris@87 601 [ 8., 9., 10., 11.]]),
Chris@87 602 array([[ 12., 13., 14., 15.]]),
Chris@87 603 array([], dtype=float64)]
Chris@87 604
Chris@87 605 With a higher dimensional array the split is still along the first axis.
Chris@87 606
Chris@87 607 >>> x = np.arange(8.0).reshape(2, 2, 2)
Chris@87 608 >>> x
Chris@87 609 array([[[ 0., 1.],
Chris@87 610 [ 2., 3.]],
Chris@87 611 [[ 4., 5.],
Chris@87 612 [ 6., 7.]]])
Chris@87 613 >>> np.vsplit(x, 2)
Chris@87 614 [array([[[ 0., 1.],
Chris@87 615 [ 2., 3.]]]),
Chris@87 616 array([[[ 4., 5.],
Chris@87 617 [ 6., 7.]]])]
Chris@87 618
Chris@87 619 """
Chris@87 620 if len(_nx.shape(ary)) < 2:
Chris@87 621 raise ValueError('vsplit only works on arrays of 2 or more dimensions')
Chris@87 622 return split(ary, indices_or_sections, 0)
Chris@87 623
Chris@87 624 def dsplit(ary, indices_or_sections):
Chris@87 625 """
Chris@87 626 Split array into multiple sub-arrays along the 3rd axis (depth).
Chris@87 627
Chris@87 628 Please refer to the `split` documentation. `dsplit` is equivalent
Chris@87 629 to `split` with ``axis=2``, the array is always split along the third
Chris@87 630 axis provided the array dimension is greater than or equal to 3.
Chris@87 631
Chris@87 632 See Also
Chris@87 633 --------
Chris@87 634 split : Split an array into multiple sub-arrays of equal size.
Chris@87 635
Chris@87 636 Examples
Chris@87 637 --------
Chris@87 638 >>> x = np.arange(16.0).reshape(2, 2, 4)
Chris@87 639 >>> x
Chris@87 640 array([[[ 0., 1., 2., 3.],
Chris@87 641 [ 4., 5., 6., 7.]],
Chris@87 642 [[ 8., 9., 10., 11.],
Chris@87 643 [ 12., 13., 14., 15.]]])
Chris@87 644 >>> np.dsplit(x, 2)
Chris@87 645 [array([[[ 0., 1.],
Chris@87 646 [ 4., 5.]],
Chris@87 647 [[ 8., 9.],
Chris@87 648 [ 12., 13.]]]),
Chris@87 649 array([[[ 2., 3.],
Chris@87 650 [ 6., 7.]],
Chris@87 651 [[ 10., 11.],
Chris@87 652 [ 14., 15.]]])]
Chris@87 653 >>> np.dsplit(x, np.array([3, 6]))
Chris@87 654 [array([[[ 0., 1., 2.],
Chris@87 655 [ 4., 5., 6.]],
Chris@87 656 [[ 8., 9., 10.],
Chris@87 657 [ 12., 13., 14.]]]),
Chris@87 658 array([[[ 3.],
Chris@87 659 [ 7.]],
Chris@87 660 [[ 11.],
Chris@87 661 [ 15.]]]),
Chris@87 662 array([], dtype=float64)]
Chris@87 663
Chris@87 664 """
Chris@87 665 if len(_nx.shape(ary)) < 3:
Chris@87 666 raise ValueError('dsplit only works on arrays of 3 or more dimensions')
Chris@87 667 return split(ary, indices_or_sections, 2)
Chris@87 668
Chris@87 669 def get_array_prepare(*args):
Chris@87 670 """Find the wrapper for the array with the highest priority.
Chris@87 671
Chris@87 672 In case of ties, leftmost wins. If no wrapper is found, return None
Chris@87 673 """
Chris@87 674 wrappers = sorted((getattr(x, '__array_priority__', 0), -i,
Chris@87 675 x.__array_prepare__) for i, x in enumerate(args)
Chris@87 676 if hasattr(x, '__array_prepare__'))
Chris@87 677 if wrappers:
Chris@87 678 return wrappers[-1][-1]
Chris@87 679 return None
Chris@87 680
Chris@87 681 def get_array_wrap(*args):
Chris@87 682 """Find the wrapper for the array with the highest priority.
Chris@87 683
Chris@87 684 In case of ties, leftmost wins. If no wrapper is found, return None
Chris@87 685 """
Chris@87 686 wrappers = sorted((getattr(x, '__array_priority__', 0), -i,
Chris@87 687 x.__array_wrap__) for i, x in enumerate(args)
Chris@87 688 if hasattr(x, '__array_wrap__'))
Chris@87 689 if wrappers:
Chris@87 690 return wrappers[-1][-1]
Chris@87 691 return None
Chris@87 692
Chris@87 693 def kron(a, b):
Chris@87 694 """
Chris@87 695 Kronecker product of two arrays.
Chris@87 696
Chris@87 697 Computes the Kronecker product, a composite array made of blocks of the
Chris@87 698 second array scaled by the first.
Chris@87 699
Chris@87 700 Parameters
Chris@87 701 ----------
Chris@87 702 a, b : array_like
Chris@87 703
Chris@87 704 Returns
Chris@87 705 -------
Chris@87 706 out : ndarray
Chris@87 707
Chris@87 708 See Also
Chris@87 709 --------
Chris@87 710 outer : The outer product
Chris@87 711
Chris@87 712 Notes
Chris@87 713 -----
Chris@87 714 The function assumes that the number of dimenensions of `a` and `b`
Chris@87 715 are the same, if necessary prepending the smallest with ones.
Chris@87 716 If `a.shape = (r0,r1,..,rN)` and `b.shape = (s0,s1,...,sN)`,
Chris@87 717 the Kronecker product has shape `(r0*s0, r1*s1, ..., rN*SN)`.
Chris@87 718 The elements are products of elements from `a` and `b`, organized
Chris@87 719 explicitly by::
Chris@87 720
Chris@87 721 kron(a,b)[k0,k1,...,kN] = a[i0,i1,...,iN] * b[j0,j1,...,jN]
Chris@87 722
Chris@87 723 where::
Chris@87 724
Chris@87 725 kt = it * st + jt, t = 0,...,N
Chris@87 726
Chris@87 727 In the common 2-D case (N=1), the block structure can be visualized::
Chris@87 728
Chris@87 729 [[ a[0,0]*b, a[0,1]*b, ... , a[0,-1]*b ],
Chris@87 730 [ ... ... ],
Chris@87 731 [ a[-1,0]*b, a[-1,1]*b, ... , a[-1,-1]*b ]]
Chris@87 732
Chris@87 733
Chris@87 734 Examples
Chris@87 735 --------
Chris@87 736 >>> np.kron([1,10,100], [5,6,7])
Chris@87 737 array([ 5, 6, 7, 50, 60, 70, 500, 600, 700])
Chris@87 738 >>> np.kron([5,6,7], [1,10,100])
Chris@87 739 array([ 5, 50, 500, 6, 60, 600, 7, 70, 700])
Chris@87 740
Chris@87 741 >>> np.kron(np.eye(2), np.ones((2,2)))
Chris@87 742 array([[ 1., 1., 0., 0.],
Chris@87 743 [ 1., 1., 0., 0.],
Chris@87 744 [ 0., 0., 1., 1.],
Chris@87 745 [ 0., 0., 1., 1.]])
Chris@87 746
Chris@87 747 >>> a = np.arange(100).reshape((2,5,2,5))
Chris@87 748 >>> b = np.arange(24).reshape((2,3,4))
Chris@87 749 >>> c = np.kron(a,b)
Chris@87 750 >>> c.shape
Chris@87 751 (2, 10, 6, 20)
Chris@87 752 >>> I = (1,3,0,2)
Chris@87 753 >>> J = (0,2,1)
Chris@87 754 >>> J1 = (0,) + J # extend to ndim=4
Chris@87 755 >>> S1 = (1,) + b.shape
Chris@87 756 >>> K = tuple(np.array(I) * np.array(S1) + np.array(J1))
Chris@87 757 >>> c[K] == a[I]*b[J]
Chris@87 758 True
Chris@87 759
Chris@87 760 """
Chris@87 761 b = asanyarray(b)
Chris@87 762 a = array(a, copy=False, subok=True, ndmin=b.ndim)
Chris@87 763 ndb, nda = b.ndim, a.ndim
Chris@87 764 if (nda == 0 or ndb == 0):
Chris@87 765 return _nx.multiply(a, b)
Chris@87 766 as_ = a.shape
Chris@87 767 bs = b.shape
Chris@87 768 if not a.flags.contiguous:
Chris@87 769 a = reshape(a, as_)
Chris@87 770 if not b.flags.contiguous:
Chris@87 771 b = reshape(b, bs)
Chris@87 772 nd = ndb
Chris@87 773 if (ndb != nda):
Chris@87 774 if (ndb > nda):
Chris@87 775 as_ = (1,)*(ndb-nda) + as_
Chris@87 776 else:
Chris@87 777 bs = (1,)*(nda-ndb) + bs
Chris@87 778 nd = nda
Chris@87 779 result = outer(a, b).reshape(as_+bs)
Chris@87 780 axis = nd-1
Chris@87 781 for _ in range(nd):
Chris@87 782 result = concatenate(result, axis=axis)
Chris@87 783 wrapper = get_array_prepare(a, b)
Chris@87 784 if wrapper is not None:
Chris@87 785 result = wrapper(result)
Chris@87 786 wrapper = get_array_wrap(a, b)
Chris@87 787 if wrapper is not None:
Chris@87 788 result = wrapper(result)
Chris@87 789 return result
Chris@87 790
Chris@87 791
Chris@87 792 def tile(A, reps):
Chris@87 793 """
Chris@87 794 Construct an array by repeating A the number of times given by reps.
Chris@87 795
Chris@87 796 If `reps` has length ``d``, the result will have dimension of
Chris@87 797 ``max(d, A.ndim)``.
Chris@87 798
Chris@87 799 If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new
Chris@87 800 axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication,
Chris@87 801 or shape (1, 1, 3) for 3-D replication. If this is not the desired
Chris@87 802 behavior, promote `A` to d-dimensions manually before calling this
Chris@87 803 function.
Chris@87 804
Chris@87 805 If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it.
Chris@87 806 Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as
Chris@87 807 (1, 1, 2, 2).
Chris@87 808
Chris@87 809 Parameters
Chris@87 810 ----------
Chris@87 811 A : array_like
Chris@87 812 The input array.
Chris@87 813 reps : array_like
Chris@87 814 The number of repetitions of `A` along each axis.
Chris@87 815
Chris@87 816 Returns
Chris@87 817 -------
Chris@87 818 c : ndarray
Chris@87 819 The tiled output array.
Chris@87 820
Chris@87 821 See Also
Chris@87 822 --------
Chris@87 823 repeat : Repeat elements of an array.
Chris@87 824
Chris@87 825 Examples
Chris@87 826 --------
Chris@87 827 >>> a = np.array([0, 1, 2])
Chris@87 828 >>> np.tile(a, 2)
Chris@87 829 array([0, 1, 2, 0, 1, 2])
Chris@87 830 >>> np.tile(a, (2, 2))
Chris@87 831 array([[0, 1, 2, 0, 1, 2],
Chris@87 832 [0, 1, 2, 0, 1, 2]])
Chris@87 833 >>> np.tile(a, (2, 1, 2))
Chris@87 834 array([[[0, 1, 2, 0, 1, 2]],
Chris@87 835 [[0, 1, 2, 0, 1, 2]]])
Chris@87 836
Chris@87 837 >>> b = np.array([[1, 2], [3, 4]])
Chris@87 838 >>> np.tile(b, 2)
Chris@87 839 array([[1, 2, 1, 2],
Chris@87 840 [3, 4, 3, 4]])
Chris@87 841 >>> np.tile(b, (2, 1))
Chris@87 842 array([[1, 2],
Chris@87 843 [3, 4],
Chris@87 844 [1, 2],
Chris@87 845 [3, 4]])
Chris@87 846
Chris@87 847 """
Chris@87 848 try:
Chris@87 849 tup = tuple(reps)
Chris@87 850 except TypeError:
Chris@87 851 tup = (reps,)
Chris@87 852 d = len(tup)
Chris@87 853 c = _nx.array(A, copy=False, subok=True, ndmin=d)
Chris@87 854 shape = list(c.shape)
Chris@87 855 n = max(c.size, 1)
Chris@87 856 if (d < c.ndim):
Chris@87 857 tup = (1,)*(c.ndim-d) + tup
Chris@87 858 for i, nrep in enumerate(tup):
Chris@87 859 if nrep != 1:
Chris@87 860 c = c.reshape(-1, n).repeat(nrep, 0)
Chris@87 861 dim_in = shape[i]
Chris@87 862 dim_out = dim_in*nrep
Chris@87 863 shape[i] = dim_out
Chris@87 864 n //= max(dim_in, 1)
Chris@87 865 return c.reshape(shape)