| 2981 | |
| 2982 | @derived_from(pd.DataFrame) |
| 2983 | def join( |
| 2984 | self, |
| 2985 | other, |
| 2986 | on=None, |
| 2987 | how="left", |
| 2988 | lsuffix="", |
| 2989 | rsuffix="", |
| 2990 | shuffle_method=None, |
| 2991 | npartitions=None, |
| 2992 | ): |
| 2993 | if not isinstance(other, list) and not is_dask_collection(other): |
| 2994 | other = from_pandas(other, npartitions=1) |
| 2995 | if ( |
| 2996 | not isinstance(other, list) |
| 2997 | and not is_dataframe_like(other._meta) |
| 2998 | and hasattr(other._meta, "name") |
| 2999 | ): |
| 3000 | other = new_collection(expr.ToFrame(other)) |
| 3001 | |
| 3002 | if not isinstance(other, FrameBase): |
| 3003 | if not isinstance(other, list) or not all( |
| 3004 | isinstance(o, FrameBase) for o in other |
| 3005 | ): |
| 3006 | raise ValueError("other must be DataFrame or list of DataFrames") |
| 3007 | if how not in ("outer", "left"): |
| 3008 | raise ValueError("merge_multi only supports left or outer joins") |
| 3009 | |
| 3010 | other = [ |
| 3011 | from_pandas(o, npartitions=1) if not is_dask_collection(o) else o |
| 3012 | for o in other |
| 3013 | ] |
| 3014 | |
| 3015 | return new_collection( |
| 3016 | JoinRecursive([self.expr] + [o.expr for o in other], how=how) |
| 3017 | ) |
| 3018 | |
| 3019 | return self.merge( |
| 3020 | right=other, |
| 3021 | left_index=on is None, |
| 3022 | right_index=True, |
| 3023 | left_on=on, |
| 3024 | how=how, |
| 3025 | suffixes=(lsuffix, rsuffix), |
| 3026 | shuffle_method=shuffle_method, |
| 3027 | npartitions=npartitions, |
| 3028 | ) |
| 3029 | |
| 3030 | @derived_from(pd.DataFrame) |
| 3031 | def groupby( |