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