def join(self, right: 'DataFrame', on: Optional[Union[(Name, List[Name])]]=None, how: str='left', lsuffix: str='', rsuffix: str='') -> 'DataFrame':
    "\n        Join columns of another DataFrame.\n\n        Join columns with `right` DataFrame either on index or on a key column. Efficiently join\n        multiple DataFrame objects by index at once by passing a list.\n\n        Parameters\n        ----------\n        right: DataFrame, Series\n        on: str, list of str, or array-like, optional\n            Column or index level name(s) in the caller to join on the index in `right`, otherwise\n            joins index-on-index. If multiple values given, the `right` DataFrame must have a\n            MultiIndex. Can pass an array as the join key if it is not already contained in the\n            calling DataFrame. Like an Excel VLOOKUP operation.\n        how: {'left', 'right', 'outer', 'inner'}, default 'left'\n            How to handle the operation of the two objects.\n\n            * left: use `left` frame’s index (or column if on is specified).\n            * right: use `right`’s index.\n            * outer: form union of `left` frame’s index (or column if on is specified) with\n              right’s index, and sort it. lexicographically.\n            * inner: form intersection of `left` frame’s index (or column if on is specified)\n              with `right`’s index, preserving the order of the `left`’s one.\n        lsuffix : str, default ''\n            Suffix to use from left frame's overlapping columns.\n        rsuffix : str, default ''\n            Suffix to use from `right` frame's overlapping columns.\n\n        Returns\n        -------\n        DataFrame\n            A dataframe containing columns from both the `left` and `right`.\n\n        See Also\n        --------\n        DataFrame.merge: For column(s)-on-columns(s) operations.\n        DataFrame.update : Modify in place using non-NA values from another DataFrame.\n        DataFrame.hint : Specifies some hint on the current DataFrame.\n        broadcast : Marks a DataFrame as small enough for use in broadcast joins.\n\n        Notes\n        -----\n        Parameters on, lsuffix, and rsuffix are not supported when passing a list of DataFrame\n        objects.\n\n        Examples\n        --------\n        >>> psdf1 = ps.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n        ...                      'A': ['A0', 'A1', 'A2', 'A3']},\n        ...                     columns=['key', 'A'])\n        >>> psdf2 = ps.DataFrame({'key': ['K0', 'K1', 'K2'],\n        ...                      'B': ['B0', 'B1', 'B2']},\n        ...                     columns=['key', 'B'])\n        >>> psdf1\n          key   A\n        0  K0  A0\n        1  K1  A1\n        2  K2  A2\n        3  K3  A3\n        >>> psdf2\n          key   B\n        0  K0  B0\n        1  K1  B1\n        2  K2  B2\n\n        Join DataFrames using their indexes.\n\n        >>> join_psdf = psdf1.join(psdf2, lsuffix='_left', rsuffix='_right')\n        >>> join_psdf.sort_values(by=join_psdf.columns)\n          key_left   A key_right     B\n        0       K0  A0        K0    B0\n        1       K1  A1        K1    B1\n        2       K2  A2        K2    B2\n        3       K3  A3      None  None\n\n        If we want to join using the key columns, we need to set key to be the index in both df and\n        right. The joined DataFrame will have key as its index.\n\n        >>> join_psdf = psdf1.set_index('key').join(psdf2.set_index('key'))\n        >>> join_psdf.sort_values(by=join_psdf.columns) # doctest: +NORMALIZE_WHITESPACE\n              A     B\n        key\n        K0   A0    B0\n        K1   A1    B1\n        K2   A2    B2\n        K3   A3  None\n\n        Another option to join using the key columns is to use the on parameter. DataFrame.join\n        always uses right’s index but we can use any column in df. This method not preserve the\n        original DataFrame’s index in the result unlike pandas.\n\n        >>> join_psdf = psdf1.join(psdf2.set_index('key'), on='key')\n        >>> join_psdf.index\n        Int64Index([0, 1, 2, 3], dtype='int64')\n        "
    if isinstance(right, ps.Series):
        common = list(self.columns.intersection([right.name]))
    else:
        common = list(self.columns.intersection(right.columns))
    if ((len(common) > 0) and (not lsuffix) and (not rsuffix)):
        raise ValueError('columns overlap but no suffix specified: {rename}'.format(rename=common))
    need_set_index = False
    if on:
        if (not is_list_like(on)):
            on = [on]
        if (len(on) != right._internal.index_level):
            raise ValueError('len(left_on) must equal the number of levels in the index of "right"')
        need_set_index = (len((set(on) & set(self.index.names))) == 0)
    if need_set_index:
        self = self.set_index(on)
    join_psdf = self.merge(right, left_index=True, right_index=True, how=how, suffixes=(lsuffix, rsuffix))
    return (join_psdf.reset_index() if need_set_index else join_psdf)
Join columns of another DataFrame.

Join columns with `right` DataFrame either on index or on a key column. Efficiently join
multiple DataFrame objects by index at once by passing a list.

Parameters
----------
right: DataFrame, Series
on: str, list of str, or array-like, optional
    Column or index level name(s) in the caller to join on the index in `right`, otherwise
    joins index-on-index. If multiple values given, the `right` DataFrame must have a
    MultiIndex. Can pass an array as the join key if it is not already contained in the
    calling DataFrame. Like an Excel VLOOKUP operation.
how: {'left', 'right', 'outer', 'inner'}, default 'left'
    How to handle the operation of the two objects.

    * left: use `left` frame’s index (or column if on is specified).
    * right: use `right`’s index.
    * outer: form union of `left` frame’s index (or column if on is specified) with
      right’s index, and sort it. lexicographically.
    * inner: form intersection of `left` frame’s index (or column if on is specified)
      with `right`’s index, preserving the order of the `left`’s one.
lsuffix : str, default ''
    Suffix to use from left frame's overlapping columns.
rsuffix : str, default ''
    Suffix to use from `right` frame's overlapping columns.

Returns
-------
DataFrame
    A dataframe containing columns from both the `left` and `right`.

See Also
--------
DataFrame.merge: For column(s)-on-columns(s) operations.
DataFrame.update : Modify in place using non-NA values from another DataFrame.
DataFrame.hint : Specifies some hint on the current DataFrame.
broadcast : Marks a DataFrame as small enough for use in broadcast joins.

Notes
-----
Parameters on, lsuffix, and rsuffix are not supported when passing a list of DataFrame
objects.

Examples
--------
>>> psdf1 = ps.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
...                      'A': ['A0', 'A1', 'A2', 'A3']},
...                     columns=['key', 'A'])
>>> psdf2 = ps.DataFrame({'key': ['K0', 'K1', 'K2'],
...                      'B': ['B0', 'B1', 'B2']},
...                     columns=['key', 'B'])
>>> psdf1
  key   A
0  K0  A0
1  K1  A1
2  K2  A2
3  K3  A3
>>> psdf2
  key   B
0  K0  B0
1  K1  B1
2  K2  B2

Join DataFrames using their indexes.

>>> join_psdf = psdf1.join(psdf2, lsuffix='_left', rsuffix='_right')
>>> join_psdf.sort_values(by=join_psdf.columns)
  key_left   A key_right     B
0       K0  A0        K0    B0
1       K1  A1        K1    B1
2       K2  A2        K2    B2
3       K3  A3      None  None

If we want to join using the key columns, we need to set key to be the index in both df and
right. The joined DataFrame will have key as its index.

>>> join_psdf = psdf1.set_index('key').join(psdf2.set_index('key'))
>>> join_psdf.sort_values(by=join_psdf.columns) # doctest: +NORMALIZE_WHITESPACE
      A     B
key
K0   A0    B0
K1   A1    B1
K2   A2    B2
K3   A3  None

Another option to join using the key columns is to use the on parameter. DataFrame.join
always uses right’s index but we can use any column in df. This method not preserve the
original DataFrame’s index in the result unlike pandas.

>>> join_psdf = psdf1.join(psdf2.set_index('key'), on='key')
>>> join_psdf.index
Int64Index([0, 1, 2, 3], dtype='int64')
def join(self, right: 'DataFrame', on: Optional[Union[(Name, List[Name])]]=None, how: str='left', lsuffix: str=, rsuffix: str=) -> 'DataFrame':
    "\n        Join columns of another DataFrame.\n\n        Join columns with `right` DataFrame either on index or on a key column. Efficiently join\n        multiple DataFrame objects by index at once by passing a list.\n\n        Parameters\n        ----------\n        right: DataFrame, Series\n        on: str, list of str, or array-like, optional\n            Column or index level name(s) in the caller to join on the index in `right`, otherwise\n            joins index-on-index. If multiple values given, the `right` DataFrame must have a\n            MultiIndex. Can pass an array as the join key if it is not already contained in the\n            calling DataFrame. Like an Excel VLOOKUP operation.\n        how: {'left', 'right', 'outer', 'inner'}, default 'left'\n            How to handle the operation of the two objects.\n\n            * left: use `left` frame’s index (or column if on is specified).\n            * right: use `right`’s index.\n            * outer: form union of `left` frame’s index (or column if on is specified) with\n              right’s index, and sort it. lexicographically.\n            * inner: form intersection of `left` frame’s index (or column if on is specified)\n              with `right`’s index, preserving the order of the `left`’s one.\n        lsuffix : str, default \n            Suffix to use from left frame's overlapping columns.\n        rsuffix : str, default \n            Suffix to use from `right` frame's overlapping columns.\n\n        Returns\n        -------\n        DataFrame\n            A dataframe containing columns from both the `left` and `right`.\n\n        See Also\n        --------\n        DataFrame.merge: For column(s)-on-columns(s) operations.\n        DataFrame.update : Modify in place using non-NA values from another DataFrame.\n        DataFrame.hint : Specifies some hint on the current DataFrame.\n        broadcast : Marks a DataFrame as small enough for use in broadcast joins.\n\n        Notes\n        -----\n        Parameters on, lsuffix, and rsuffix are not supported when passing a list of DataFrame\n        objects.\n\n        Examples\n        --------\n        >>> psdf1 = ps.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n        ...                      'A': ['A0', 'A1', 'A2', 'A3']},\n        ...                     columns=['key', 'A'])\n        >>> psdf2 = ps.DataFrame({'key': ['K0', 'K1', 'K2'],\n        ...                      'B': ['B0', 'B1', 'B2']},\n        ...                     columns=['key', 'B'])\n        >>> psdf1\n          key   A\n        0  K0  A0\n        1  K1  A1\n        2  K2  A2\n        3  K3  A3\n        >>> psdf2\n          key   B\n        0  K0  B0\n        1  K1  B1\n        2  K2  B2\n\n        Join DataFrames using their indexes.\n\n        >>> join_psdf = psdf1.join(psdf2, lsuffix='_left', rsuffix='_right')\n        >>> join_psdf.sort_values(by=join_psdf.columns)\n          key_left   A key_right     B\n        0       K0  A0        K0    B0\n        1       K1  A1        K1    B1\n        2       K2  A2        K2    B2\n        3       K3  A3      None  None\n\n        If we want to join using the key columns, we need to set key to be the index in both df and\n        right. The joined DataFrame will have key as its index.\n\n        >>> join_psdf = psdf1.set_index('key').join(psdf2.set_index('key'))\n        >>> join_psdf.sort_values(by=join_psdf.columns) # doctest: +NORMALIZE_WHITESPACE\n              A     B\n        key\n        K0   A0    B0\n        K1   A1    B1\n        K2   A2    B2\n        K3   A3  None\n\n        Another option to join using the key columns is to use the on parameter. DataFrame.join\n        always uses right’s index but we can use any column in df. This method not preserve the\n        original DataFrame’s index in the result unlike pandas.\n\n        >>> join_psdf = psdf1.join(psdf2.set_index('key'), on='key')\n        >>> join_psdf.index\n        Int64Index([0, 1, 2, 3], dtype='int64')\n        "
    if isinstance(right, ps.Series):
        common = list(self.columns.intersection([right.name]))
    else:
        common = list(self.columns.intersection(right.columns))
    if ((len(common) > 0) and (not lsuffix) and (not rsuffix)):
        raise ValueError('columns overlap but no suffix specified: {rename}'.format(rename=common))
    need_set_index = False
    if on:
        if (not is_list_like(on)):
            on = [on]
        if (len(on) != right._internal.index_level):
            raise ValueError('len(left_on) must equal the number of levels in the index of "right"')
        need_set_index = (len((set(on) & set(self.index.names))) == 0)
    if need_set_index:
        self = self.set_index(on)
    join_psdf = self.merge(right, left_index=True, right_index=True, how=how, suffixes=(lsuffix, rsuffix))
    return (join_psdf.reset_index() if need_set_index else join_psdf)