Skip to content

DataFrame.eval error fixed #59189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 18 additions & 32 deletions pandas/core/computation/align.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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):
Expand All @@ -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)

Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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_:
Expand Down
Loading