|
1 | 1 | __all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'block', 'hstack',
|
2 |
| - 'stack', 'vstack'] |
| 2 | + 'stack', 'unstack', 'vstack'] |
3 | 3 |
|
4 | 4 | import functools
|
5 | 5 | import itertools
|
|
11 | 11 | from .multiarray import array, asanyarray, normalize_axis_index
|
12 | 12 | from . import fromnumeric as _from_nx
|
13 | 13 |
|
14 |
| - |
15 | 14 | array_function_dispatch = functools.partial(
|
16 | 15 | overrides.array_function_dispatch, module='numpy')
|
17 | 16 |
|
@@ -261,6 +260,7 @@ def vstack(tup, *, dtype=None, casting="same_kind"):
|
261 | 260 | dstack : Stack arrays in sequence depth wise (along third axis).
|
262 | 261 | column_stack : Stack 1-D arrays as columns into a 2-D array.
|
263 | 262 | vsplit : Split an array into multiple sub-arrays vertically (row-wise).
|
| 263 | + unstack : Split an array into a tuple of sub-arrays along an axis. |
264 | 264 |
|
265 | 265 | Examples
|
266 | 266 | --------
|
@@ -331,8 +331,9 @@ def hstack(tup, *, dtype=None, casting="same_kind"):
|
331 | 331 | vstack : Stack arrays in sequence vertically (row wise).
|
332 | 332 | dstack : Stack arrays in sequence depth wise (along third axis).
|
333 | 333 | column_stack : Stack 1-D arrays as columns into a 2-D array.
|
334 |
| - hsplit : Split an array into multiple sub-arrays |
| 334 | + hsplit : Split an array into multiple sub-arrays |
335 | 335 | horizontally (column-wise).
|
| 336 | + unstack : Split an array into a tuple of sub-arrays along an axis. |
336 | 337 |
|
337 | 338 | Examples
|
338 | 339 | --------
|
@@ -414,6 +415,7 @@ def stack(arrays, axis=0, out=None, *, dtype=None, casting="same_kind"):
|
414 | 415 | concatenate : Join a sequence of arrays along an existing axis.
|
415 | 416 | block : Assemble an nd-array from nested lists of blocks.
|
416 | 417 | split : Split array into a list of multiple sub-arrays of equal size.
|
| 418 | + unstack : Split an array into a tuple of sub-arrays along an axis. |
417 | 419 |
|
418 | 420 | Examples
|
419 | 421 | --------
|
@@ -456,6 +458,76 @@ def stack(arrays, axis=0, out=None, *, dtype=None, casting="same_kind"):
|
456 | 458 | return _nx.concatenate(expanded_arrays, axis=axis, out=out,
|
457 | 459 | dtype=dtype, casting=casting)
|
458 | 460 |
|
| 461 | +def _unstack_dispatcher(x, /, *, axis=None): |
| 462 | + return (x,) |
| 463 | + |
| 464 | +@array_function_dispatch(_unstack_dispatcher) |
| 465 | +def unstack(x, /, *, axis=0): |
| 466 | + """ |
| 467 | + Split an array into a sequence of arrays along the given axis. |
| 468 | +
|
| 469 | + The ``axis`` parameter specifies the dimension along which the array will |
| 470 | + be split. For example, if ``axis=0`` (the default) it will be the first |
| 471 | + dimension and if ``axis=-1`` it will be the last dimension. |
| 472 | +
|
| 473 | + The result is a tuple of arrays split along ``axis``. |
| 474 | +
|
| 475 | + .. versionadded:: 2.1.0 |
| 476 | +
|
| 477 | + Parameters |
| 478 | + ---------- |
| 479 | + x : ndarray |
| 480 | + The array to be unstacked. |
| 481 | + axis : int, optional |
| 482 | + Axis along which the array will be split. Default: ``0``. |
| 483 | +
|
| 484 | + Returns |
| 485 | + ------- |
| 486 | + unstacked : tuple of ndarrays |
| 487 | + The unstacked arrays. |
| 488 | +
|
| 489 | + See Also |
| 490 | + -------- |
| 491 | + stack : Join a sequence of arrays along a new axis. |
| 492 | + concatenate : Join a sequence of arrays along an existing axis. |
| 493 | + block : Assemble an nd-array from nested lists of blocks. |
| 494 | + split : Split array into a list of multiple sub-arrays of equal size. |
| 495 | +
|
| 496 | + Notes |
| 497 | + ----- |
| 498 | + ``unstack`` serves as the reverse operation of :py:func:`stack`, i.e., |
| 499 | + ``stack(unstack(x, axis=axis), axis=axis) == x``. |
| 500 | +
|
| 501 | + This function is equivalent to ``tuple(np.moveaxis(x, axis, 0))``, since |
| 502 | + iterating on an array iterates along the first axis. |
| 503 | +
|
| 504 | + Examples |
| 505 | + -------- |
| 506 | + >>> arr = np.arange(24).reshape((2, 3, 4)) |
| 507 | + >>> np.unstack(arr) |
| 508 | + (array([[ 0, 1, 2, 3], |
| 509 | + [ 4, 5, 6, 7], |
| 510 | + [ 8, 9, 10, 11]]), |
| 511 | + array([[12, 13, 14, 15], |
| 512 | + [16, 17, 18, 19], |
| 513 | + [20, 21, 22, 23]])) |
| 514 | + >>> np.unstack(arr, axis=1) |
| 515 | + (array([[ 0, 1, 2, 3], |
| 516 | + [12, 13, 14, 15]]), |
| 517 | + array([[ 4, 5, 6, 7], |
| 518 | + [16, 17, 18, 19]]), |
| 519 | + array([[ 8, 9, 10, 11], |
| 520 | + [20, 21, 22, 23]])) |
| 521 | + >>> arr2 = np.stack(np.unstack(arr, axis=1), axis=1) |
| 522 | + >>> arr2.shape |
| 523 | + (2, 3, 4) |
| 524 | + >>> np.all(arr == arr2) |
| 525 | + np.True_ |
| 526 | +
|
| 527 | + """ |
| 528 | + if x.ndim == 0: |
| 529 | + raise ValueError("Input array must be at least 1-d.") |
| 530 | + return tuple(_nx.moveaxis(x, axis, 0)) |
459 | 531 |
|
460 | 532 | # Internal functions to eliminate the overhead of repeated dispatch in one of
|
461 | 533 | # the two possible paths inside np.block.
|
@@ -710,7 +782,7 @@ def block(arrays):
|
710 | 782 | second-last dimension (-2), and so on until the outermost list is reached.
|
711 | 783 |
|
712 | 784 | Blocks can be of any dimension, but will not be broadcasted using
|
713 |
| - the normal rules. Instead, leading axes of size 1 are inserted, |
| 785 | + the normal rules. Instead, leading axes of size 1 are inserted, |
714 | 786 | to make ``block.ndim`` the same for all blocks. This is primarily useful
|
715 | 787 | for working with scalars, and means that code like ``np.block([v, 1])``
|
716 | 788 | is valid, where ``v.ndim == 1``.
|
@@ -756,6 +828,7 @@ def block(arrays):
|
756 | 828 | dstack : Stack arrays in sequence depth wise (along third axis).
|
757 | 829 | column_stack : Stack 1-D arrays as columns into a 2-D array.
|
758 | 830 | vsplit : Split an array into multiple sub-arrays vertically (row-wise).
|
| 831 | + unstack : Split an array into a tuple of sub-arrays along an axis. |
759 | 832 |
|
760 | 833 | Notes
|
761 | 834 | -----
|
|
0 commit comments