def mad(self, axis: Axis=0) -> 'Series':
    "\n        Return the mean absolute deviation of values.\n\n        Parameters\n        ----------\n        axis : {index (0), columns (1)}\n            Axis for the function to be applied on.\n\n        Examples\n        --------\n        >>> df = ps.DataFrame({'a': [1, 2, 3, np.nan], 'b': [0.1, 0.2, 0.3, np.nan]},\n        ...                   columns=['a', 'b'])\n\n        >>> df.mad()\n        a    0.666667\n        b    0.066667\n        dtype: float64\n\n        >>> df.mad(axis=1)\n        0    0.45\n        1    0.90\n        2    1.35\n        3     NaN\n        dtype: float64\n        "
    from pyspark.pandas.series import first_series
    axis = validate_axis(axis)
    if (axis == 0):

        def get_spark_column(psdf: DataFrame, label: Label) -> Column:
            scol = psdf._internal.spark_column_for(label)
            col_type = psdf._internal.spark_type_for(label)
            if isinstance(col_type, BooleanType):
                scol = scol.cast('integer')
            return scol
        new_column_labels: List[Label] = []
        for label in self._internal.column_labels:
            dtype = self._psser_for(label).spark.data_type
            if isinstance(dtype, (NumericType, BooleanType)):
                new_column_labels.append(label)
        new_columns = [F.avg(get_spark_column(self, label)).alias(name_like_string(label)) for label in new_column_labels]
        mean_data = self._internal.spark_frame.select(*new_columns).first()
        new_columns = [F.avg(F.abs((get_spark_column(self, label) - mean_data[name_like_string(label)]))).alias(name_like_string(label)) for label in new_column_labels]
        sdf = self._internal.spark_frame.select(*[SF.lit(None).cast(StringType()).alias(SPARK_DEFAULT_INDEX_NAME)], *new_columns)
        with ps.option_context('compute.max_rows', 1):
            internal = InternalFrame(spark_frame=sdf, index_spark_columns=[scol_for(sdf, SPARK_DEFAULT_INDEX_NAME)], column_labels=new_column_labels, column_label_names=self._internal.column_label_names)
            return first_series(DataFrame(internal).transpose())
    else:

        @pandas_udf(returnType=DoubleType())
        def calculate_columns_axis(*cols: pd.Series) -> pd.Series:
            return pd.concat(cols, axis=1).mad(axis=1)
        internal = self._internal.copy(column_labels=[None], data_spark_columns=[calculate_columns_axis(*self._internal.data_spark_columns).alias(SPARK_DEFAULT_SERIES_NAME)], data_fields=[None], column_label_names=None)
        return first_series(DataFrame(internal))
Return the mean absolute deviation of values.

Parameters
----------
axis : {index (0), columns (1)}
    Axis for the function to be applied on.

Examples
--------
>>> df = ps.DataFrame({'a': [1, 2, 3, np.nan], 'b': [0.1, 0.2, 0.3, np.nan]},
...                   columns=['a', 'b'])

>>> df.mad()
a    0.666667
b    0.066667
dtype: float64

>>> df.mad(axis=1)
0    0.45
1    0.90
2    1.35
3     NaN
dtype: float64
def mad(self, axis: Axis=0) -> 'Series':
    "\n        Return the mean absolute deviation of values.\n\n        Parameters\n        ----------\n        axis : {index (0), columns (1)}\n            Axis for the function to be applied on.\n\n        Examples\n        --------\n        >>> df = ps.DataFrame({'a': [1, 2, 3, np.nan], 'b': [0.1, 0.2, 0.3, np.nan]},\n        ...                   columns=['a', 'b'])\n\n        >>> df.mad()\n        a    0.666667\n        b    0.066667\n        dtype: float64\n\n        >>> df.mad(axis=1)\n        0    0.45\n        1    0.90\n        2    1.35\n        3     NaN\n        dtype: float64\n        "
    from pyspark.pandas.series import first_series
    axis = validate_axis(axis)
    if (axis == 0):

        def get_spark_column(psdf: DataFrame, label: Label) -> Column:
            scol = psdf._internal.spark_column_for(label)
            col_type = psdf._internal.spark_type_for(label)
            if isinstance(col_type, BooleanType):
                scol = scol.cast('integer')
            return scol
        new_column_labels: List[Label] = []
        for label in self._internal.column_labels:
            dtype = self._psser_for(label).spark.data_type
            if isinstance(dtype, (NumericType, BooleanType)):
                new_column_labels.append(label)
        new_columns = [F.avg(get_spark_column(self, label)).alias(name_like_string(label)) for label in new_column_labels]
        mean_data = self._internal.spark_frame.select(*new_columns).first()
        new_columns = [F.avg(F.abs((get_spark_column(self, label) - mean_data[name_like_string(label)]))).alias(name_like_string(label)) for label in new_column_labels]
        sdf = self._internal.spark_frame.select(*[SF.lit(None).cast(StringType()).alias(SPARK_DEFAULT_INDEX_NAME)], *new_columns)
        with ps.option_context('compute.max_rows', 1):
            internal = InternalFrame(spark_frame=sdf, index_spark_columns=[scol_for(sdf, SPARK_DEFAULT_INDEX_NAME)], column_labels=new_column_labels, column_label_names=self._internal.column_label_names)
            return first_series(DataFrame(internal).transpose())
    else:

        @pandas_udf(returnType=DoubleType())
        def calculate_columns_axis(*cols: pd.Series) -> pd.Series:
            return pd.concat(cols, axis=1).mad(axis=1)
        internal = self._internal.copy(column_labels=[None], data_spark_columns=[calculate_columns_axis(*self._internal.data_spark_columns).alias(SPARK_DEFAULT_SERIES_NAME)], data_fields=[None], column_label_names=None)
        return first_series(DataFrame(internal))