from __future__ import division, absolute_import, print_function __all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack', 'stack'] from . import numeric as _nx from .numeric import asanyarray, newaxis def atleast_1d(*arys): """ Convert inputs to arrays with at least one dimension. Scalar inputs are converted to 1-dimensional arrays, whilst higher-dimensional inputs are preserved. Parameters ---------- arys1, arys2, ... : array_like One or more input arrays. Returns ------- ret : ndarray An array, or sequence of arrays, each with ``a.ndim >= 1``. Copies are made only if necessary. See Also -------- atleast_2d, atleast_3d Examples -------- >>> np.atleast_1d(1.0) array([ 1.]) >>> x = np.arange(9.0).reshape(3,3) >>> np.atleast_1d(x) array([[ 0., 1., 2.], [ 3., 4., 5.], [ 6., 7., 8.]]) >>> np.atleast_1d(x) is x True >>> np.atleast_1d(1, [3, 4]) [array([1]), array([3, 4])] """ res = [] for ary in arys: ary = asanyarray(ary) if len(ary.shape) == 0: result = ary.reshape(1) else: result = ary res.append(result) if len(res) == 1: return res[0] else: return res def atleast_2d(*arys): """ View inputs as arrays with at least two dimensions. Parameters ---------- arys1, arys2, ... : array_like One or more array-like sequences. Non-array inputs are converted to arrays. Arrays that already have two or more dimensions are preserved. Returns ------- res, res2, ... : ndarray An array, or tuple of arrays, each with ``a.ndim >= 2``. Copies are avoided where possible, and views with two or more dimensions are returned. See Also -------- atleast_1d, atleast_3d Examples -------- >>> np.atleast_2d(3.0) array([[ 3.]]) >>> x = np.arange(3.0) >>> np.atleast_2d(x) array([[ 0., 1., 2.]]) >>> np.atleast_2d(x).base is x True >>> np.atleast_2d(1, [1, 2], [[1, 2]]) [array([[1]]), array([[1, 2]]), array([[1, 2]])] """ res = [] for ary in arys: ary = asanyarray(ary) if len(ary.shape) == 0: result = ary.reshape(1, 1) elif len(ary.shape) == 1: result = ary[newaxis,:] else: result = ary res.append(result) if len(res) == 1: return res[0] else: return res def atleast_3d(*arys): """ View inputs as arrays with at least three dimensions. Parameters ---------- arys1, arys2, ... : array_like One or more array-like sequences. Non-array inputs are converted to arrays. Arrays that already have three or more dimensions are preserved. Returns ------- res1, res2, ... : ndarray An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are avoided where possible, and views with three or more dimensions are returned. For example, a 1-D array of shape ``(N,)`` becomes a view of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a view of shape ``(M, N, 1)``. See Also -------- atleast_1d, atleast_2d Examples -------- >>> np.atleast_3d(3.0) array([[[ 3.]]]) >>> x = np.arange(3.0) >>> np.atleast_3d(x).shape (1, 3, 1) >>> x = np.arange(12.0).reshape(4,3) >>> np.atleast_3d(x).shape (4, 3, 1) >>> np.atleast_3d(x).base is x True >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): ... print(arr, arr.shape) ... [[[1] [2]]] (1, 2, 1) [[[1] [2]]] (1, 2, 1) [[[1 2]]] (1, 1, 2) """ res = [] for ary in arys: ary = asanyarray(ary) if len(ary.shape) == 0: result = ary.reshape(1, 1, 1) elif len(ary.shape) == 1: result = ary[newaxis,:, newaxis] elif len(ary.shape) == 2: result = ary[:,:, newaxis] else: result = ary res.append(result) if len(res) == 1: return res[0] else: return res def vstack(tup): """ Stack arrays in sequence vertically (row wise). Take a sequence of arrays and stack them vertically to make a single array. Rebuild arrays divided by `vsplit`. Parameters ---------- tup : sequence of ndarrays Tuple containing arrays to be stacked. The arrays must have the same shape along all but the first axis. Returns ------- stacked : ndarray The array formed by stacking the given arrays. See Also -------- stack : Join a sequence of arrays along a new axis. hstack : Stack arrays in sequence horizontally (column wise). dstack : Stack arrays in sequence depth wise (along third dimension). concatenate : Join a sequence of arrays along an existing axis. vsplit : Split array into a list of multiple sub-arrays vertically. Notes ----- Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that are at least 2-dimensional. Examples -------- >>> a = np.array([1, 2, 3]) >>> b = np.array([2, 3, 4]) >>> np.vstack((a,b)) array([[1, 2, 3], [2, 3, 4]]) >>> a = np.array([[1], [2], [3]]) >>> b = np.array([[2], [3], [4]]) >>> np.vstack((a,b)) array([[1], [2], [3], [2], [3], [4]]) """ return _nx.concatenate([atleast_2d(_m) for _m in tup], 0) def hstack(tup): """ Stack arrays in sequence horizontally (column wise). Take a sequence of arrays and stack them horizontally to make a single array. Rebuild arrays divided by `hsplit`. Parameters ---------- tup : sequence of ndarrays All arrays must have the same shape along all but the second axis. Returns ------- stacked : ndarray The array formed by stacking the given arrays. See Also -------- stack : Join a sequence of arrays along a new axis. vstack : Stack arrays in sequence vertically (row wise). dstack : Stack arrays in sequence depth wise (along third axis). concatenate : Join a sequence of arrays along an existing axis. hsplit : Split array along second axis. Notes ----- Equivalent to ``np.concatenate(tup, axis=1)`` Examples -------- >>> a = np.array((1,2,3)) >>> b = np.array((2,3,4)) >>> np.hstack((a,b)) array([1, 2, 3, 2, 3, 4]) >>> a = np.array([[1],[2],[3]]) >>> b = np.array([[2],[3],[4]]) >>> np.hstack((a,b)) array([[1, 2], [2, 3], [3, 4]]) """ arrs = [atleast_1d(_m) for _m in tup] # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" if arrs[0].ndim == 1: return _nx.concatenate(arrs, 0) else: return _nx.concatenate(arrs, 1) def stack(arrays, axis=0): """ Join a sequence of arrays along a new axis. The `axis` parameter specifies the index of the new axis in the dimensions of the result. For example, if ``axis=0`` it will be the first dimension and if ``axis=-1`` it will be the last dimension. .. versionadded:: 1.10.0 Parameters ---------- arrays : sequence of array_like Each array must have the same shape. axis : int, optional The axis in the result array along which the input arrays are stacked. Returns ------- stacked : ndarray The stacked array has one more dimension than the input arrays. See Also -------- concatenate : Join a sequence of arrays along an existing axis. split : Split array into a list of multiple sub-arrays of equal size. Examples -------- >>> arrays = [np.random.randn(3, 4) for _ in range(10)] >>> np.stack(arrays, axis=0).shape (10, 3, 4) >>> np.stack(arrays, axis=1).shape (3, 10, 4) >>> np.stack(arrays, axis=2).shape (3, 4, 10) >>> a = np.array([1, 2, 3]) >>> b = np.array([2, 3, 4]) >>> np.stack((a, b)) array([[1, 2, 3], [2, 3, 4]]) >>> np.stack((a, b), axis=-1) array([[1, 2], [2, 3], [3, 4]]) """ arrays = [asanyarray(arr) for arr in arrays] if not arrays: raise ValueError('need at least one array to stack') shapes = set(arr.shape for arr in arrays) if len(shapes) != 1: raise ValueError('all input arrays must have the same shape') result_ndim = arrays[0].ndim + 1 if not -result_ndim <= axis < result_ndim: msg = 'axis {0} out of bounds [-{1}, {1})'.format(axis, result_ndim) raise IndexError(msg) if axis < 0: axis += result_ndim sl = (slice(None),) * axis + (_nx.newaxis,) expanded_arrays = [arr[sl] for arr in arrays] return _nx.concatenate(expanded_arrays, axis=axis)