def unstack(self) -> DataFrameOrSeries:
    '\n        Pivot the (necessarily hierarchical) index labels.\n\n        Returns a DataFrame having a new level of column labels whose inner-most level\n        consists of the pivoted index labels.\n\n        If the index is not a MultiIndex, the output will be a Series.\n\n        .. note:: If the index is a MultiIndex, the output DataFrame could be very wide, and\n            it could cause a serious performance degradation since Spark partitions it row based.\n\n        Returns\n        -------\n        Series or DataFrame\n\n        See Also\n        --------\n        DataFrame.pivot : Pivot a table based on column values.\n        DataFrame.stack : Pivot a level of the column labels (inverse operation from unstack).\n\n        Examples\n        --------\n        >>> df = ps.DataFrame({"A": {"0": "a", "1": "b", "2": "c"},\n        ...                    "B": {"0": "1", "1": "3", "2": "5"},\n        ...                    "C": {"0": "2", "1": "4", "2": "6"}},\n        ...                   columns=["A", "B", "C"])\n        >>> df\n           A  B  C\n        0  a  1  2\n        1  b  3  4\n        2  c  5  6\n\n        >>> df.unstack().sort_index()\n        A  0    a\n           1    b\n           2    c\n        B  0    1\n           1    3\n           2    5\n        C  0    2\n           1    4\n           2    6\n        dtype: object\n\n        >>> df.columns = pd.MultiIndex.from_tuples([(\'X\', \'A\'), (\'X\', \'B\'), (\'Y\', \'C\')])\n        >>> df.unstack().sort_index()\n        X  A  0    a\n              1    b\n              2    c\n           B  0    1\n              1    3\n              2    5\n        Y  C  0    2\n              1    4\n              2    6\n        dtype: object\n\n        For MultiIndex case:\n\n        >>> df = ps.DataFrame({"A": ["a", "b", "c"],\n        ...                    "B": [1, 3, 5],\n        ...                    "C": [2, 4, 6]},\n        ...                   columns=["A", "B", "C"])\n        >>> df = df.set_index(\'A\', append=True)\n        >>> df  # doctest: +NORMALIZE_WHITESPACE\n             B  C\n          A\n        0 a  1  2\n        1 b  3  4\n        2 c  5  6\n        >>> df.unstack().sort_index()  # doctest: +NORMALIZE_WHITESPACE\n             B              C\n        A    a    b    c    a    b    c\n        0  1.0  NaN  NaN  2.0  NaN  NaN\n        1  NaN  3.0  NaN  NaN  4.0  NaN\n        2  NaN  NaN  5.0  NaN  NaN  6.0\n        '
    from pyspark.pandas.series import first_series
    if (self._internal.index_level > 1):
        with option_context('compute.default_index_type', 'distributed'):
            df = self.reset_index()
        index = df._internal.column_labels[:(self._internal.index_level - 1)]
        columns = df.columns[(self._internal.index_level - 1)]
        df = df.pivot_table(index=index, columns=columns, values=self._internal.column_labels, aggfunc='first')
        internal = df._internal.copy(index_names=self._internal.index_names[:(- 1)], index_fields=df._internal.index_fields[:(self._internal.index_level - 1)], column_label_names=(df._internal.column_label_names[:(- 1)] + [(None if (self._internal.index_names[(- 1)] is None) else df._internal.column_label_names[(- 1)])]))
        return DataFrame(internal)
    column_labels = self._internal.column_labels
    ser_name = SPARK_DEFAULT_SERIES_NAME
    sdf = self._internal.spark_frame
    new_index_columns = [SPARK_INDEX_NAME_FORMAT(i) for i in range(self._internal.column_labels_level)]
    new_index_map = list(zip_longest(new_index_columns, self._internal.column_label_names, []))
    pairs = F.explode(F.array(*[F.struct(*[SF.lit(c).alias(name) for (c, name) in zip(idx, new_index_columns)], *[self._internal.spark_column_for(idx).alias(ser_name)]) for idx in column_labels]))
    columns = ([F.col(('pairs.%s' % name)) for name in new_index_columns[:self._internal.column_labels_level]] + [F.col(('pairs.%s' % ser_name))])
    new_index_len = len(new_index_columns)
    existing_index_columns = []
    for (i, (index_name, index_field)) in enumerate(zip(self._internal.index_names, self._internal.index_fields)):
        name = SPARK_INDEX_NAME_FORMAT((i + new_index_len))
        new_index_map.append((name, index_name, index_field.copy(name=name)))
        existing_index_columns.append(self._internal.index_spark_columns[i].alias(name))
    exploded_df = sdf.withColumn('pairs', pairs).select((existing_index_columns + columns))
    (index_spark_column_names, index_names, index_fields) = zip(*new_index_map)
    return first_series(DataFrame(InternalFrame(exploded_df, index_spark_columns=[scol_for(exploded_df, col) for col in index_spark_column_names], index_names=list(index_names), index_fields=list(index_fields), column_labels=[None])))
Pivot the (necessarily hierarchical) index labels.

Returns a DataFrame having a new level of column labels whose inner-most level
consists of the pivoted index labels.

If the index is not a MultiIndex, the output will be a Series.

.. note:: If the index is a MultiIndex, the output DataFrame could be very wide, and
    it could cause a serious performance degradation since Spark partitions it row based.

Returns
-------
Series or DataFrame

See Also
--------
DataFrame.pivot : Pivot a table based on column values.
DataFrame.stack : Pivot a level of the column labels (inverse operation from unstack).

Examples
--------
>>> df = ps.DataFrame({"A": {"0": "a", "1": "b", "2": "c"},
...                    "B": {"0": "1", "1": "3", "2": "5"},
...                    "C": {"0": "2", "1": "4", "2": "6"}},
...                   columns=["A", "B", "C"])
>>> df
   A  B  C
0  a  1  2
1  b  3  4
2  c  5  6

>>> df.unstack().sort_index()
A  0    a
   1    b
   2    c
B  0    1
   1    3
   2    5
C  0    2
   1    4
   2    6
dtype: object

>>> df.columns = pd.MultiIndex.from_tuples([('X', 'A'), ('X', 'B'), ('Y', 'C')])
>>> df.unstack().sort_index()
X  A  0    a
      1    b
      2    c
   B  0    1
      1    3
      2    5
Y  C  0    2
      1    4
      2    6
dtype: object

For MultiIndex case:

>>> df = ps.DataFrame({"A": ["a", "b", "c"],
...                    "B": [1, 3, 5],
...                    "C": [2, 4, 6]},
...                   columns=["A", "B", "C"])
>>> df = df.set_index('A', append=True)
>>> df  # doctest: +NORMALIZE_WHITESPACE
     B  C
  A
0 a  1  2
1 b  3  4
2 c  5  6
>>> df.unstack().sort_index()  # doctest: +NORMALIZE_WHITESPACE
     B              C
A    a    b    c    a    b    c
0  1.0  NaN  NaN  2.0  NaN  NaN
1  NaN  3.0  NaN  NaN  4.0  NaN
2  NaN  NaN  5.0  NaN  NaN  6.0
def unstack(self) -> DataFrameOrSeries:
    '\n        Pivot the (necessarily hierarchical) index labels.\n\n        Returns a DataFrame having a new level of column labels whose inner-most level\n        consists of the pivoted index labels.\n\n        If the index is not a MultiIndex, the output will be a Series.\n\n        .. note:: If the index is a MultiIndex, the output DataFrame could be very wide, and\n            it could cause a serious performance degradation since Spark partitions it row based.\n\n        Returns\n        -------\n        Series or DataFrame\n\n        See Also\n        --------\n        DataFrame.pivot : Pivot a table based on column values.\n        DataFrame.stack : Pivot a level of the column labels (inverse operation from unstack).\n\n        Examples\n        --------\n        >>> df = ps.DataFrame({"A": {"0": "a", "1": "b", "2": "c"},\n        ...                    "B": {"0": "1", "1": "3", "2": "5"},\n        ...                    "C": {"0": "2", "1": "4", "2": "6"}},\n        ...                   columns=["A", "B", "C"])\n        >>> df\n           A  B  C\n        0  a  1  2\n        1  b  3  4\n        2  c  5  6\n\n        >>> df.unstack().sort_index()\n        A  0    a\n           1    b\n           2    c\n        B  0    1\n           1    3\n           2    5\n        C  0    2\n           1    4\n           2    6\n        dtype: object\n\n        >>> df.columns = pd.MultiIndex.from_tuples([(\'X\', \'A\'), (\'X\', \'B\'), (\'Y\', \'C\')])\n        >>> df.unstack().sort_index()\n        X  A  0    a\n              1    b\n              2    c\n           B  0    1\n              1    3\n              2    5\n        Y  C  0    2\n              1    4\n              2    6\n        dtype: object\n\n        For MultiIndex case:\n\n        >>> df = ps.DataFrame({"A": ["a", "b", "c"],\n        ...                    "B": [1, 3, 5],\n        ...                    "C": [2, 4, 6]},\n        ...                   columns=["A", "B", "C"])\n        >>> df = df.set_index(\'A\', append=True)\n        >>> df  # doctest: +NORMALIZE_WHITESPACE\n             B  C\n          A\n        0 a  1  2\n        1 b  3  4\n        2 c  5  6\n        >>> df.unstack().sort_index()  # doctest: +NORMALIZE_WHITESPACE\n             B              C\n        A    a    b    c    a    b    c\n        0  1.0  NaN  NaN  2.0  NaN  NaN\n        1  NaN  3.0  NaN  NaN  4.0  NaN\n        2  NaN  NaN  5.0  NaN  NaN  6.0\n        '
    from pyspark.pandas.series import first_series
    if (self._internal.index_level > 1):
        with option_context('compute.default_index_type', 'distributed'):
            df = self.reset_index()
        index = df._internal.column_labels[:(self._internal.index_level - 1)]
        columns = df.columns[(self._internal.index_level - 1)]
        df = df.pivot_table(index=index, columns=columns, values=self._internal.column_labels, aggfunc='first')
        internal = df._internal.copy(index_names=self._internal.index_names[:(- 1)], index_fields=df._internal.index_fields[:(self._internal.index_level - 1)], column_label_names=(df._internal.column_label_names[:(- 1)] + [(None if (self._internal.index_names[(- 1)] is None) else df._internal.column_label_names[(- 1)])]))
        return DataFrame(internal)
    column_labels = self._internal.column_labels
    ser_name = SPARK_DEFAULT_SERIES_NAME
    sdf = self._internal.spark_frame
    new_index_columns = [SPARK_INDEX_NAME_FORMAT(i) for i in range(self._internal.column_labels_level)]
    new_index_map = list(zip_longest(new_index_columns, self._internal.column_label_names, []))
    pairs = F.explode(F.array(*[F.struct(*[SF.lit(c).alias(name) for (c, name) in zip(idx, new_index_columns)], *[self._internal.spark_column_for(idx).alias(ser_name)]) for idx in column_labels]))
    columns = ([F.col(('pairs.%s' % name)) for name in new_index_columns[:self._internal.column_labels_level]] + [F.col(('pairs.%s' % ser_name))])
    new_index_len = len(new_index_columns)
    existing_index_columns = []
    for (i, (index_name, index_field)) in enumerate(zip(self._internal.index_names, self._internal.index_fields)):
        name = SPARK_INDEX_NAME_FORMAT((i + new_index_len))
        new_index_map.append((name, index_name, index_field.copy(name=name)))
        existing_index_columns.append(self._internal.index_spark_columns[i].alias(name))
    exploded_df = sdf.withColumn('pairs', pairs).select((existing_index_columns + columns))
    (index_spark_column_names, index_names, index_fields) = zip(*new_index_map)
    return first_series(DataFrame(InternalFrame(exploded_df, index_spark_columns=[scol_for(exploded_df, col) for col in index_spark_column_names], index_names=list(index_names), index_fields=list(index_fields), column_labels=[None])))