Returns a new QueryCompiler with modes calculated for each label along given axis.

        Returns:
            A new QueryCompiler with modes calculated.

def mode(self, **kwargs):
        """Returns a new QueryCompiler with modes calculated for each label along given axis.

        Returns:
            A new QueryCompiler with modes calculated.
        """
        axis = kwargs.get("axis", 0)

        def mode_builder(df, **kwargs):
            result = df.mode(**kwargs)
            # We return a dataframe with the same shape as the input to ensure
            # that all the partitions will be the same shape
            if not axis and len(df) != len(result):
                # Pad columns
                append_values = pandas.DataFrame(
                    columns=result.columns, index=range(len(result), len(df))
                )
                result = pandas.concat([result, append_values], ignore_index=True)
            elif axis and len(df.columns) != len(result.columns):
                # Pad rows
                append_vals = pandas.DataFrame(
                    columns=range(len(result.columns), len(df.columns)),
                    index=result.index,
                )
                result = pandas.concat([result, append_vals], axis=1)
            return pandas.DataFrame(result)

        func = self._prepare_method(mode_builder, **kwargs)
        new_data = self._map_across_full_axis(axis, func)

        new_index = pandas.RangeIndex(len(self.index)) if not axis else self.index
        new_columns = self.columns if not axis else pandas.RangeIndex(len(self.columns))
        new_dtypes = self._dtype_cache
        if new_dtypes is not None:
            new_dtypes.index = new_columns
        return self.__constructor__(
            new_data, new_index, new_columns, new_dtypes
        ).dropna(axis=axis, how="all")