diff --git a/pandas/core/computation/align.py b/pandas/core/computation/align.py index 7de4d8cdf99e1..acd30e015d157 100644 --- a/pandas/core/computation/align.py +++ b/pandas/core/computation/align.py @@ -1,20 +1,20 @@ """ Core eval alignment algorithms. """ - from __future__ import annotations from functools import ( partial, wraps, ) -from typing import TYPE_CHECKING +from typing import ( + TYPE_CHECKING, + Callable, +) import warnings import numpy as np -from pandas._config.config import get_option - from pandas.errors import PerformanceWarning from pandas.util._exceptions import find_stack_level @@ -28,10 +28,7 @@ from pandas.core.computation.common import result_type_many if TYPE_CHECKING: - from collections.abc import ( - Callable, - Sequence, - ) + from collections.abc import Sequence from pandas._typing import F @@ -113,7 +110,7 @@ def _align_core(terms): ax, itm = axis, items if not axes[ax].is_(itm): - axes[ax] = axes[ax].union(itm) + axes[ax] = axes[ax].join(itm, how="outer") for i, ndim in ndims.items(): for axis, items in zip(range(ndim), axes): @@ -127,24 +124,20 @@ def _align_core(terms): reindexer_size = len(reindexer) ordm = np.log10(max(1, abs(reindexer_size - term_axis_size))) - if ( - get_option("performance_warnings") - and ordm >= 1 - and reindexer_size >= 10000 - ): + if ordm >= 1 and reindexer_size >= 10000: w = ( f"Alignment difference on axis {axis} is larger " - f"than an order of magnitude on term {terms[i].name!r}, " + f"than an order of magnitude on term {repr(terms[i].name)}, " f"by more than {ordm:.4g}; performance may suffer." ) warnings.warn( w, category=PerformanceWarning, stacklevel=find_stack_level() ) - obj = ti.reindex(reindexer, axis=axis) + obj = ti.reindex(reindexer, axis=axis, copy=False) terms[i].update(obj) - terms[i].update(terms[i].value.values) + terms[i].update(terms[i].value) return typ, _zip_axes_from_type(typ, axes) @@ -160,24 +153,19 @@ def align_terms(terms): # can't iterate so it must just be a constant or single variable if isinstance(terms.value, (ABCSeries, ABCDataFrame)): typ = type(terms.value) - name = terms.value.name if isinstance(terms.value, ABCSeries) else None - return typ, _zip_axes_from_type(typ, terms.value.axes), name - return np.result_type(terms.type), None, None + return typ, _zip_axes_from_type(typ, terms.value.axes) + return np.result_type(terms.type), None # if all resolved variables are numeric scalars if all(term.is_scalar for term in terms): - return result_type_many(*(term.value for term in terms)).type, None, None - - # if all input series have a common name, propagate it to the returned series - names = {term.value.name for term in terms if isinstance(term.value, ABCSeries)} - name = names.pop() if len(names) == 1 else None + return result_type_many(*(term.value for term in terms)).type, None # perform the main alignment typ, axes = _align_core(terms) - return typ, axes, name + return typ, axes -def reconstruct_object(typ, obj, axes, dtype, name): +def reconstruct_object(typ, obj, axes, dtype): """ Reconstruct an object given its type, raw value, and possibly empty (None) axes. @@ -194,8 +182,8 @@ def reconstruct_object(typ, obj, axes, dtype, name): Returns ------- ret : typ - An object of type ``typ`` with the value `obj` and possible axes - `axes`. + An object of type typ with the value obj and possible axes + axes. """ try: typ = typ.type @@ -205,9 +193,7 @@ def reconstruct_object(typ, obj, axes, dtype, name): res_t = np.result_type(obj.dtype, dtype) if not isinstance(typ, partial) and issubclass(typ, PandasObject): - if name is None: - return typ(obj, dtype=res_t, **axes) - return typ(obj, dtype=res_t, name=name, **axes) + return typ(obj, dtype=res_t, **axes) # special case for pathological things like ~True/~False if hasattr(res_t, "type") and typ == np.bool_ and res_t != np.bool_: