Skip to content

Commit 2b204bd

Browse files
committed
Add some tests, use ABCseries, remove wrong docs for applymap
1 parent 8c366be commit 2b204bd

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

pandas/core/apply.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818

1919
from pandas.core.construction import create_series_with_explicit_dtype
2020
from pandas.core.frame import DataFrame
21-
from pandas.core.series import Series
2221

2322
if TYPE_CHECKING:
24-
from pandas import Index
23+
from pandas import Series, Index
2524

2625
ResType = Dict[int, Any]
2726

@@ -309,7 +308,7 @@ def apply_standard(self):
309308
if partial_result is None:
310309
return self.obj._constructor_sliced(result, index=labels)
311310
else:
312-
if isinstance(partial_result, Series):
311+
if isinstance(partial_result, ABCSeries):
313312
partial_result = DataFrame.infer_objects(partial_result)
314313

315314
# compute the result using the series generator

pandas/core/frame.py

-8
Original file line numberDiff line numberDiff line change
@@ -7307,14 +7307,6 @@ def applymap(self, func) -> "DataFrame":
73077307
--------
73087308
DataFrame.apply : Apply a function along input axis of DataFrame.
73097309
7310-
Notes
7311-
-----
7312-
In the current implementation applymap calls `func` twice on the
7313-
first column/row to decide whether it can take a fast or slow
7314-
code path. This can lead to unexpected behavior if `func` has
7315-
side-effects, as they will take effect twice for the first
7316-
column/row.
7317-
73187310
Examples
73197311
--------
73207312
>>> df = pd.DataFrame([[1, 2.12], [3.356, 4.567]])

pandas/tests/frame/test_apply.py

+32
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,38 @@ def test_apply_noreduction_tzaware_object(self):
726726
result = df.apply(lambda x: x.copy())
727727
tm.assert_frame_equal(result, df)
728728

729+
def test_apply_function_runs_once(self):
730+
# https://github.com/pandas-dev/pandas/issues/30815
731+
def non_reducing_func_with_state(row):
732+
non_reducing_func_with_state.call_count = getattr(non_reducing_func_with_state, 'call_count', 0) + 1
733+
return row * non_reducing_func_with_state.call_count
734+
735+
def reducing_func_with_state(_):
736+
reducing_func_with_state.call_count = getattr(reducing_func_with_state, 'call_count', 0) + 1
737+
return reducing_func_with_state.call_count
738+
739+
df = pd.DataFrame({'a': [1, 2, 3]})
740+
741+
# no reduction
742+
res0 = df.apply(non_reducing_func_with_state)
743+
tm.assert_frame_equal(res0, df)
744+
745+
# reduction
746+
res1 = df.apply(reducing_func_with_state)
747+
tm.assert_series_equal(res1, Series(data=[1], index=['a']))
748+
749+
def test_applymap_function_runs_once(self):
750+
751+
# This function will create the same values as in the DataFrame
752+
def func_with_state(_):
753+
func_with_state.call_count = getattr(func_with_state, 'call_count', 0) + 1
754+
return func_with_state.call_count
755+
756+
df = pd.DataFrame({'a': [1, 2, 3]})
757+
result = df.applymap(func_with_state)
758+
tm.assert_frame_equal(result, df)
759+
760+
729761

730762
class TestInferOutputShape:
731763
# the user has supplied an opaque UDF where

0 commit comments

Comments
 (0)