Groups object by one or more dimensions

        Applies groupby operation over the specified dimensions
        returning an object of type container_type (expected to be
        dictionary-like) containing the groups.

        Args:
            dimensions: Dimension(s) to group by
            container_type: Type to cast group container to
            group_type: Type to cast each group to
            dynamic: Whether to return a DynamicMap
            **kwargs: Keyword arguments to pass to each group

        Returns:
            Returns object of supplied container_type containing the
            groups. If dynamic=True returns a DynamicMap instead.

def groupby(self, dimensions, container_type=None, group_type=None, **kwargs):
        """Groups object by one or more dimensions

        Applies groupby operation over the specified dimensions
        returning an object of type container_type (expected to be
        dictionary-like) containing the groups.

        Args:
            dimensions: Dimension(s) to group by
            container_type: Type to cast group container to
            group_type: Type to cast each group to
            dynamic: Whether to return a DynamicMap
            **kwargs: Keyword arguments to pass to each group

        Returns:
            Returns object of supplied container_type containing the
            groups. If dynamic=True returns a DynamicMap instead.
        """
        if self.ndims == 1:
            self.param.warning('Cannot split Map with only one dimension.')
            return self
        elif not isinstance(dimensions, list):
            dimensions = [dimensions]
        container_type = container_type if container_type else type(self)
        group_type = group_type if group_type else type(self)
        dimensions = [self.get_dimension(d, strict=True) for d in dimensions]
        with item_check(False):
            return util.ndmapping_groupby(self, dimensions, container_type,
                                          group_type, sort=True, **kwargs)