Deploy a function along a full axis in Ray.

            Args:
                axis: The axis to perform the function along.
                func: The function to perform.
                num_splits: The number of splits to return
                    (see `split_result_of_axis_func_pandas`)
                kwargs: A dictionary of keyword arguments.
                maintain_partitioning: If True, keep the old partitioning if possible.
                    If False, create a new partition layout.
                partitions: All partitions that make up the full axis (row or column)

            Returns:
                A list of Pandas DataFrames.

def deploy_axis_func(
        cls, axis, func, num_splits, kwargs, maintain_partitioning, *partitions
    ):
        """Deploy a function along a full axis in Ray.

            Args:
                axis: The axis to perform the function along.
                func: The function to perform.
                num_splits: The number of splits to return
                    (see `split_result_of_axis_func_pandas`)
                kwargs: A dictionary of keyword arguments.
                maintain_partitioning: If True, keep the old partitioning if possible.
                    If False, create a new partition layout.
                partitions: All partitions that make up the full axis (row or column)

            Returns:
                A list of Pandas DataFrames.
            """
        # Pop these off first because they aren't expected by the function.
        manual_partition = kwargs.pop("manual_partition", False)
        lengths = kwargs.pop("_lengths", None)

        dataframe = pandas.concat(partitions, axis=axis, copy=False)
        result = func(dataframe, **kwargs)
        if isinstance(result, pandas.Series):
            if num_splits == 1:
                return result
            return [result] + [pandas.Series([]) for _ in range(num_splits - 1)]

        if manual_partition:
            # The split function is expecting a list
            lengths = list(lengths)
        # We set lengths to None so we don't use the old lengths for the resulting partition
        # layout. This is done if the number of splits is changing or we are told not to
        # keep the old partitioning.
        elif num_splits != len(partitions) or not maintain_partitioning:
            lengths = None
        else:
            if axis == 0:
                lengths = [len(part) for part in partitions]
                if sum(lengths) != len(result):
                    lengths = None
            else:
                lengths = [len(part.columns) for part in partitions]
                if sum(lengths) != len(result.columns):
                    lengths = None
        return split_result_of_axis_func_pandas(axis, num_splits, result, lengths)