|
37 | 37 | import warnings
|
38 | 38 |
|
39 | 39 | import numpy as np
|
| 40 | +import pandas as pd |
40 | 41 | from numpy import ma
|
41 | 42 |
|
42 | 43 | from pandas._config import get_option
|
|
262 | 263 | from pandas.core.internals.managers import SingleBlockManager
|
263 | 264 |
|
264 | 265 | from pandas.io.formats.style import Styler
|
265 |
| - |
266 | 266 | # ---------------------------------------------------------------------
|
267 | 267 | # Docstring templates
|
268 | 268 |
|
@@ -4877,7 +4877,9 @@ def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None:
|
4877 | 4877 | kwargs["target"] = self
|
4878 | 4878 | kwargs["resolvers"] = tuple(kwargs.get("resolvers", ())) + resolvers
|
4879 | 4879 |
|
4880 |
| - return _eval(expr, inplace=inplace, **kwargs) |
| 4880 | + result = _eval(expr, inplace=inplace, **kwargs) |
| 4881 | + |
| 4882 | + return result.__finalize__(self, method="eval") |
4881 | 4883 |
|
4882 | 4884 | def select_dtypes(self, include=None, exclude=None) -> DataFrame:
|
4883 | 4885 | """
|
@@ -11054,20 +11056,69 @@ def merge(
|
11054 | 11056 |
|
11055 | 11057 | from pandas.core.reshape.merge import merge
|
11056 | 11058 |
|
11057 |
| - return merge( |
11058 |
| - self, |
11059 |
| - right, |
11060 |
| - how=how, |
11061 |
| - on=on, |
11062 |
| - left_on=left_on, |
11063 |
| - right_on=right_on, |
11064 |
| - left_index=left_index, |
11065 |
| - right_index=right_index, |
11066 |
| - sort=sort, |
11067 |
| - suffixes=suffixes, |
11068 |
| - indicator=indicator, |
11069 |
| - validate=validate, |
11070 |
| - ) |
| 11059 | + df1 = pd.DataFrame({"name": ["Chad", "Robert", "Mike", "Sarah", "May"], |
| 11060 | + "value": [1, 2, 6, 7, 9] |
| 11061 | + }) |
| 11062 | + df2 = pd.DataFrame({"name": ["Carley", "Name", "July", "Sarah", "May"], |
| 11063 | + "value": [4, 5, 6, 7, 9] |
| 11064 | + }) |
| 11065 | + df1.merge(df2, how='inner', on='value') |
| 11066 | + |
| 11067 | + # Determine join keys |
| 11068 | + if on: |
| 11069 | + left_key = right_key = on |
| 11070 | + else: |
| 11071 | + left_key = left_on |
| 11072 | + right_key = right_on |
| 11073 | + |
| 11074 | + if not left_key or not right_key: |
| 11075 | + raise ValueError("Must specify 'on' or both 'left_on' and 'right_on'") |
| 11076 | + |
| 11077 | + result = [] |
| 11078 | + |
| 11079 | + right_indexed = {} |
| 11080 | + for r_row in right.data: |
| 11081 | + key = r_row[right_key] |
| 11082 | + right_indexed.setdefault(key, []).append(r_row) |
| 11083 | + |
| 11084 | + matched_keys = set() |
| 11085 | + |
| 11086 | + for l_row in self.data: |
| 11087 | + key = l_row[left_key] |
| 11088 | + r_matches = right_indexed.get(key) |
| 11089 | + |
| 11090 | + if r_matches: |
| 11091 | + for r_row in r_matches: |
| 11092 | + joined = {} |
| 11093 | + for k, v in l_row.items(): |
| 11094 | + joined[k] = v |
| 11095 | + for k, v in r_row.items(): |
| 11096 | + if k == right_key and left_key == right_key: |
| 11097 | + continue |
| 11098 | + elif k in joined: |
| 11099 | + joined[k + suffixes[1]] = v |
| 11100 | + else: |
| 11101 | + joined[k] = v |
| 11102 | + result.append(joined) |
| 11103 | + matched_keys.add(key) |
| 11104 | + elif how in ("left", "outer"): |
| 11105 | + result.append({**l_row, **{k: None for k in right.columns - {right_key}}}) |
| 11106 | + |
| 11107 | + if how in ("right", "outer"): |
| 11108 | + left_keys = {row[left_key] for row in self.data} |
| 11109 | + for r_row in right.data: |
| 11110 | + key = r_row[right_key] |
| 11111 | + if key not in matched_keys and key not in left_keys: |
| 11112 | + row = {k: None for k in self.columns} |
| 11113 | + row.update({k: v for k, v in r_row.items()}) |
| 11114 | + result.append(row) |
| 11115 | + |
| 11116 | + if sort: |
| 11117 | + result.sort(key=lambda x: x.get(left_key)) |
| 11118 | + |
| 11119 | + return result.__finalize__(self, method="merge") |
| 11120 | + |
| 11121 | + |
11071 | 11122 |
|
11072 | 11123 | def round(
|
11073 | 11124 | self, decimals: int | dict[IndexLabel, int] | Series = 0, *args, **kwargs
|
|
0 commit comments