Skip to content

Commit a559e65

Browse files
jorisvandenbosschemeeseeksmachine
authored andcommitted
Backport PR pandas-dev#39260: REGR: fix numpy accumulate ufuncs for DataFrame
1 parent b9b61fc commit a559e65

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

doc/source/whatsnew/v1.2.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Fixed regressions
3232
- Fixed regression in :meth:`DataFrame.replace` raising ``ValueError`` when :class:`DataFrame` has dtype ``bytes`` (:issue:`38900`)
3333
- Fixed regression in :meth:`Series.fillna` that raised ``RecursionError`` with ``datetime64[ns, UTC]`` dtype (:issue:`38851`)
3434
- Fixed regression in comparisons between ``NaT`` and ``datetime.date`` objects incorrectly returning ``True`` (:issue:`39151`)
35+
- Fixed regression in calling NumPy :func:`~numpy.ufunc.accumulate` ufuncs on DataFrames, e.g. ``np.maximum.accumulate(df)`` (:issue:`39259`)
3536
- Fixed regression in repr of float-like strings of an ``object`` dtype having trailing 0's truncated after the decimal (:issue:`38708`)
3637
- Fixed regression that raised ``AttributeError`` with PyArrow versions [0.16.0, 1.0.0) (:issue:`38801`)
3738
- Fixed regression in :func:`pandas.testing.assert_frame_equal` raising ``TypeError`` with ``check_like=True`` when :class:`Index` or columns have mixed dtype (:issue:`39168`)

pandas/core/arraylike.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,14 @@ def reconstruct(result):
274274
result = getattr(ufunc, method)(*inputs, **kwargs)
275275
else:
276276
# ufunc(dataframe)
277-
mgr = inputs[0]._mgr
278-
result = mgr.apply(getattr(ufunc, method))
277+
if method == "__call__":
278+
# for np.<ufunc>(..) calls
279+
mgr = inputs[0]._mgr
280+
result = mgr.apply(getattr(ufunc, method))
281+
else:
282+
# otherwise specific ufunc methods (eg np.<ufunc>.accumulate(..))
283+
# Those can have an axis keyword and thus can't be called block-by-block
284+
result = getattr(ufunc, method)(np.asarray(inputs[0]), **kwargs)
279285

280286
if ufunc.nout > 1: # type: ignore[attr-defined]
281287
result = tuple(reconstruct(x) for x in result)

pandas/tests/frame/test_ufunc.py

+21
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,27 @@ def test_binary_frame_series_raises():
105105
np.logaddexp(df["A"], df)
106106

107107

108+
def test_unary_accumulate_axis():
109+
# https://github.com/pandas-dev/pandas/issues/39259
110+
df = pd.DataFrame({"a": [1, 3, 2, 4]})
111+
result = np.maximum.accumulate(df)
112+
expected = pd.DataFrame({"a": [1, 3, 3, 4]})
113+
tm.assert_frame_equal(result, expected)
114+
115+
df = pd.DataFrame({"a": [1, 3, 2, 4], "b": [0.1, 4.0, 3.0, 2.0]})
116+
result = np.maximum.accumulate(df)
117+
# in theory could preserve int dtype for default axis=0
118+
expected = pd.DataFrame({"a": [1.0, 3.0, 3.0, 4.0], "b": [0.1, 4.0, 4.0, 4.0]})
119+
tm.assert_frame_equal(result, expected)
120+
121+
result = np.maximum.accumulate(df, axis=0)
122+
tm.assert_frame_equal(result, expected)
123+
124+
result = np.maximum.accumulate(df, axis=1)
125+
expected = pd.DataFrame({"a": [1.0, 3.0, 2.0, 4.0], "b": [1.0, 4.0, 3.0, 4.0]})
126+
tm.assert_frame_equal(result, expected)
127+
128+
108129
def test_frame_outer_deprecated():
109130
df = pd.DataFrame({"A": [1, 2]})
110131
with tm.assert_produces_warning(FutureWarning):

0 commit comments

Comments
 (0)