|
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