Source code for hbutils.collection.dimension

"""
Overview:
    Dimension operations.
"""
__all__ = [
    'cube_shape', 'dimension_switch', 'swap_2d',
]


def _s_cube_shape(c, path):
    if isinstance(c, (list, tuple)):
        n = len(c)
        if n == 0:
            return (0,)
        else:
            first = c[0]
            first_shape = _s_cube_shape(first, (*path, 0))
            for i, item in enumerate(c[1:], start=1):
                item_shape = _s_cube_shape(item, (*path, i))
                if first_shape != item_shape:
                    raise ValueError(f'Mismatching between {repr((*path, 0))} and {repr((*path, 1))}, '
                                     f'this is not a cube!', ((*path, 0), first_shape), ((*path, 1), item_shape))
            return (n, *first_shape)
    else:
        return ()


[docs]def cube_shape(c): """ Overview: Get the shape of cube array. When it is not a cube, raise ``ValueError``. Arguments: - c: The given cube. Returns: - shape: Shape of the cube. Examples:: >>> import numpy >>> from hbutils.collection import cube_shape >>> a = numpy.random.randint(-5, 15, (3, 5, 7, 9)).tolist() >>> cube_shape(a) (3, 5, 7, 9) """ return _s_cube_shape(c, ())
[docs]def dimension_switch(c, dimensions): """ Overview: Switch the dimensions of the cube array. Arguments: - c: Multiple dimensioned array. - dimensions: New order of dimensions, should be a tuple of 0 - N-1. Returns: - switched: Switched array. Examples:: >>> import numpy >>> from hbutils.collection import cube_shape, dimension_switch >>> a = numpy.random.randint(-5, 15, (3, 5, 7, 9)).tolist() >>> cube_shape(a) (3, 5, 7, 9) >>> b = dimension_switch(a, (3, 0, 2, 1)) >>> cube_shape(b) (9, 3, 7, 5) """ shape = cube_shape(c) n = len(shape) if sorted(set(dimensions)) != list(range(len(shape))): raise ValueError(f'Invalid dimensions - {repr(dimensions)}.', dimensions) def _recursive(p, path): if p >= n: actual_path = [None] * n for i, di in enumerate(dimensions): actual_path[di] = path[i] oc = c for ip in actual_path: oc = oc[ip] return oc else: return [_recursive(p + 1, (*path, i)) for i in range(shape[dimensions[p]])] return _recursive(0, ())
[docs]def swap_2d(c): """ Overview: Swap 2d array's dimension. Arguments: - c: 2d array. Returns: - swapped: Swapped array. Examples:: >>> from hbutils.collection import swap_2d >>> swap_2d([ ... [9, 6, 4, 11, 5, -2, 1], ... [0, 0, 11, 5, 8, -4, 9], ... [0, 2, 13, 7, 0, 13, 0] ... ]) [[9, 0, 0], [6, 0, 2], [4, 11, 13], [11, 5, 7], [5, 8, 0], [-2, -4, 13], [1, 9, 0]] """ return dimension_switch(c, (1, 0))