def _sort(self, by: List[Column], ascending: Union[(bool, List[bool])], na_position: str, keep: str='first') -> 'DataFrame':
    if isinstance(ascending, bool):
        ascending = ([ascending] * len(by))
    if (len(ascending) != len(by)):
        raise ValueError('Length of ascending ({}) != length of by ({})'.format(len(ascending), len(by)))
    if (na_position not in ('first', 'last')):
        raise ValueError("invalid na_position: '{}'".format(na_position))
    mapper = {(True, 'first'): Column.asc_nulls_first, (True, 'last'): Column.asc_nulls_last, (False, 'first'): Column.desc_nulls_first, (False, 'last'): Column.desc_nulls_last}
    by = [mapper[(asc, na_position)](scol) for (scol, asc) in zip(by, ascending)]
    natural_order_scol = F.col(NATURAL_ORDER_COLUMN_NAME)
    if (keep == 'last'):
        natural_order_scol = Column.desc(natural_order_scol)
    elif (keep == 'all'):
        raise NotImplementedError('`keep`=all is not implemented yet.')
    elif (keep != 'first'):
        raise ValueError('keep must be either "first", "last" or "all".')
    sdf = self._internal.resolved_copy.spark_frame.sort(*by, natural_order_scol)
    return DataFrame(self._internal.with_new_sdf(sdf))
def _sort(self, by: List[Column], ascending: Union[(bool, List[bool])], na_position: str, keep: str='first') -> 'DataFrame':
    if isinstance(ascending, bool):
        ascending = ([ascending] * len(by))
    if (len(ascending) != len(by)):
        raise ValueError('Length of ascending ({}) != length of by ({})'.format(len(ascending), len(by)))
    if (na_position not in ('first', 'last')):
        raise ValueError("invalid na_position: '{}'".format(na_position))
    mapper = {(True, 'first'): Column.asc_nulls_first, (True, 'last'): Column.asc_nulls_last, (False, 'first'): Column.desc_nulls_first, (False, 'last'): Column.desc_nulls_last}
    by = [mapper[(asc, na_position)](scol) for (scol, asc) in zip(by, ascending)]
    natural_order_scol = F.col(NATURAL_ORDER_COLUMN_NAME)
    if (keep == 'last'):
        natural_order_scol = Column.desc(natural_order_scol)
    elif (keep == 'all'):
        raise NotImplementedError('`keep`=all is not implemented yet.')
    elif (keep != 'first'):
        raise ValueError('keep must be either "first", "last" or "all".')
    sdf = self._internal.resolved_copy.spark_frame.sort(*by, natural_order_scol)
    return DataFrame(self._internal.with_new_sdf(sdf))