Skip to content

Commit 9083281

Browse files
authored
CLN: Separate transform tests (#36146)
1 parent 2b72203 commit 9083281

File tree

5 files changed

+157
-78
lines changed

5 files changed

+157
-78
lines changed

pandas/tests/frame/apply/test_frame_apply.py

+1-48
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from collections import OrderedDict
22
from datetime import datetime
33
from itertools import chain
4-
import operator
54
import warnings
65

76
import numpy as np
@@ -14,6 +13,7 @@
1413
import pandas._testing as tm
1514
from pandas.core.apply import frame_apply
1615
from pandas.core.base import SpecificationError
16+
from pandas.tests.frame.common import zip_frames
1717

1818

1919
@pytest.fixture
@@ -1058,25 +1058,6 @@ def test_consistency_for_boxed(self, box, int_frame_const_col):
10581058
tm.assert_frame_equal(result, expected)
10591059

10601060

1061-
def zip_frames(frames, axis=1):
1062-
"""
1063-
take a list of frames, zip them together under the
1064-
assumption that these all have the first frames' index/columns.
1065-
1066-
Returns
1067-
-------
1068-
new_frame : DataFrame
1069-
"""
1070-
if axis == 1:
1071-
columns = frames[0].columns
1072-
zipped = [f.loc[:, c] for c in columns for f in frames]
1073-
return pd.concat(zipped, axis=1)
1074-
else:
1075-
index = frames[0].index
1076-
zipped = [f.loc[i, :] for i in index for f in frames]
1077-
return pd.DataFrame(zipped)
1078-
1079-
10801061
class TestDataFrameAggregate:
10811062
def test_agg_transform(self, axis, float_frame):
10821063
other_axis = 1 if axis in {0, "index"} else 0
@@ -1087,16 +1068,10 @@ def test_agg_transform(self, axis, float_frame):
10871068
f_sqrt = np.sqrt(float_frame)
10881069

10891070
# ufunc
1090-
result = float_frame.transform(np.sqrt, axis=axis)
10911071
expected = f_sqrt.copy()
1092-
tm.assert_frame_equal(result, expected)
1093-
10941072
result = float_frame.apply(np.sqrt, axis=axis)
10951073
tm.assert_frame_equal(result, expected)
10961074

1097-
result = float_frame.transform(np.sqrt, axis=axis)
1098-
tm.assert_frame_equal(result, expected)
1099-
11001075
# list-like
11011076
result = float_frame.apply([np.sqrt], axis=axis)
11021077
expected = f_sqrt.copy()
@@ -1110,9 +1085,6 @@ def test_agg_transform(self, axis, float_frame):
11101085
)
11111086
tm.assert_frame_equal(result, expected)
11121087

1113-
result = float_frame.transform([np.sqrt], axis=axis)
1114-
tm.assert_frame_equal(result, expected)
1115-
11161088
# multiple items in list
11171089
# these are in the order as if we are applying both
11181090
# functions per series and then concatting
@@ -1128,38 +1100,19 @@ def test_agg_transform(self, axis, float_frame):
11281100
)
11291101
tm.assert_frame_equal(result, expected)
11301102

1131-
result = float_frame.transform([np.abs, "sqrt"], axis=axis)
1132-
tm.assert_frame_equal(result, expected)
1133-
11341103
def test_transform_and_agg_err(self, axis, float_frame):
11351104
# cannot both transform and agg
1136-
msg = "transforms cannot produce aggregated results"
1137-
with pytest.raises(ValueError, match=msg):
1138-
float_frame.transform(["max", "min"], axis=axis)
1139-
11401105
msg = "cannot combine transform and aggregation operations"
11411106
with pytest.raises(ValueError, match=msg):
11421107
with np.errstate(all="ignore"):
11431108
float_frame.agg(["max", "sqrt"], axis=axis)
11441109

1145-
with pytest.raises(ValueError, match=msg):
1146-
with np.errstate(all="ignore"):
1147-
float_frame.transform(["max", "sqrt"], axis=axis)
1148-
11491110
df = pd.DataFrame({"A": range(5), "B": 5})
11501111

11511112
def f():
11521113
with np.errstate(all="ignore"):
11531114
df.agg({"A": ["abs", "sum"], "B": ["mean", "max"]}, axis=axis)
11541115

1155-
@pytest.mark.parametrize("method", ["abs", "shift", "pct_change", "cumsum", "rank"])
1156-
def test_transform_method_name(self, method):
1157-
# GH 19760
1158-
df = pd.DataFrame({"A": [-1, 2]})
1159-
result = df.transform(method)
1160-
expected = operator.methodcaller(method)(df)
1161-
tm.assert_frame_equal(result, expected)
1162-
11631116
def test_demo(self):
11641117
# demonstration tests
11651118
df = pd.DataFrame({"A": range(5), "B": 5})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import operator
2+
3+
import numpy as np
4+
import pytest
5+
6+
import pandas as pd
7+
import pandas._testing as tm
8+
from pandas.tests.frame.common import zip_frames
9+
10+
11+
def test_agg_transform(axis, float_frame):
12+
other_axis = 1 if axis in {0, "index"} else 0
13+
14+
with np.errstate(all="ignore"):
15+
16+
f_abs = np.abs(float_frame)
17+
f_sqrt = np.sqrt(float_frame)
18+
19+
# ufunc
20+
result = float_frame.transform(np.sqrt, axis=axis)
21+
expected = f_sqrt.copy()
22+
tm.assert_frame_equal(result, expected)
23+
24+
result = float_frame.transform(np.sqrt, axis=axis)
25+
tm.assert_frame_equal(result, expected)
26+
27+
# list-like
28+
expected = f_sqrt.copy()
29+
if axis in {0, "index"}:
30+
expected.columns = pd.MultiIndex.from_product(
31+
[float_frame.columns, ["sqrt"]]
32+
)
33+
else:
34+
expected.index = pd.MultiIndex.from_product([float_frame.index, ["sqrt"]])
35+
result = float_frame.transform([np.sqrt], axis=axis)
36+
tm.assert_frame_equal(result, expected)
37+
38+
# multiple items in list
39+
# these are in the order as if we are applying both
40+
# functions per series and then concatting
41+
expected = zip_frames([f_abs, f_sqrt], axis=other_axis)
42+
if axis in {0, "index"}:
43+
expected.columns = pd.MultiIndex.from_product(
44+
[float_frame.columns, ["absolute", "sqrt"]]
45+
)
46+
else:
47+
expected.index = pd.MultiIndex.from_product(
48+
[float_frame.index, ["absolute", "sqrt"]]
49+
)
50+
result = float_frame.transform([np.abs, "sqrt"], axis=axis)
51+
tm.assert_frame_equal(result, expected)
52+
53+
54+
def test_transform_and_agg_err(axis, float_frame):
55+
# cannot both transform and agg
56+
msg = "transforms cannot produce aggregated results"
57+
with pytest.raises(ValueError, match=msg):
58+
float_frame.transform(["max", "min"], axis=axis)
59+
60+
msg = "cannot combine transform and aggregation operations"
61+
with pytest.raises(ValueError, match=msg):
62+
with np.errstate(all="ignore"):
63+
float_frame.transform(["max", "sqrt"], axis=axis)
64+
65+
66+
@pytest.mark.parametrize("method", ["abs", "shift", "pct_change", "cumsum", "rank"])
67+
def test_transform_method_name(method):
68+
# GH 19760
69+
df = pd.DataFrame({"A": [-1, 2]})
70+
result = df.transform(method)
71+
expected = operator.methodcaller(method)(df)
72+
tm.assert_frame_equal(result, expected)

pandas/tests/frame/common.py

+24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
from typing import List
2+
3+
from pandas import DataFrame, concat
4+
5+
16
def _check_mixed_float(df, dtype=None):
27
# float16 are most likely to be upcasted to float32
38
dtypes = dict(A="float32", B="float32", C="float16", D="float64")
@@ -29,3 +34,22 @@ def _check_mixed_int(df, dtype=None):
2934
assert df.dtypes["C"] == dtypes["C"]
3035
if dtypes.get("D"):
3136
assert df.dtypes["D"] == dtypes["D"]
37+
38+
39+
def zip_frames(frames: List[DataFrame], axis: int = 1) -> DataFrame:
40+
"""
41+
take a list of frames, zip them together under the
42+
assumption that these all have the first frames' index/columns.
43+
44+
Returns
45+
-------
46+
new_frame : DataFrame
47+
"""
48+
if axis == 1:
49+
columns = frames[0].columns
50+
zipped = [f.loc[:, c] for c in columns for f in frames]
51+
return concat(zipped, axis=1)
52+
else:
53+
index = frames[0].index
54+
zipped = [f.loc[i, :] for i in index for f in frames]
55+
return DataFrame(zipped)

pandas/tests/series/apply/test_series_apply.py

+1-30
Original file line numberDiff line numberDiff line change
@@ -209,25 +209,16 @@ def test_transform(self, string_series):
209209
f_abs = np.abs(string_series)
210210

211211
# ufunc
212-
result = string_series.transform(np.sqrt)
213212
expected = f_sqrt.copy()
214-
tm.assert_series_equal(result, expected)
215-
216213
result = string_series.apply(np.sqrt)
217214
tm.assert_series_equal(result, expected)
218215

219216
# list-like
220-
result = string_series.transform([np.sqrt])
217+
result = string_series.apply([np.sqrt])
221218
expected = f_sqrt.to_frame().copy()
222219
expected.columns = ["sqrt"]
223220
tm.assert_frame_equal(result, expected)
224221

225-
result = string_series.transform([np.sqrt])
226-
tm.assert_frame_equal(result, expected)
227-
228-
result = string_series.transform(["sqrt"])
229-
tm.assert_frame_equal(result, expected)
230-
231222
# multiple items in list
232223
# these are in the order as if we are applying both functions per
233224
# series and then concatting
@@ -236,10 +227,6 @@ def test_transform(self, string_series):
236227
result = string_series.apply([np.sqrt, np.abs])
237228
tm.assert_frame_equal(result, expected)
238229

239-
result = string_series.transform(["sqrt", "abs"])
240-
expected.columns = ["sqrt", "abs"]
241-
tm.assert_frame_equal(result, expected)
242-
243230
# dict, provide renaming
244231
expected = pd.concat([f_sqrt, f_abs], axis=1)
245232
expected.columns = ["foo", "bar"]
@@ -250,19 +237,11 @@ def test_transform(self, string_series):
250237

251238
def test_transform_and_agg_error(self, string_series):
252239
# we are trying to transform with an aggregator
253-
msg = "transforms cannot produce aggregated results"
254-
with pytest.raises(ValueError, match=msg):
255-
string_series.transform(["min", "max"])
256-
257240
msg = "cannot combine transform and aggregation"
258241
with pytest.raises(ValueError, match=msg):
259242
with np.errstate(all="ignore"):
260243
string_series.agg(["sqrt", "max"])
261244

262-
with pytest.raises(ValueError, match=msg):
263-
with np.errstate(all="ignore"):
264-
string_series.transform(["sqrt", "max"])
265-
266245
msg = "cannot perform both aggregation and transformation"
267246
with pytest.raises(ValueError, match=msg):
268247
with np.errstate(all="ignore"):
@@ -463,14 +442,6 @@ def test_agg_cython_table_raises(self, series, func, expected):
463442
# e.g. Series('a b'.split()).cumprod() will raise
464443
series.agg(func)
465444

466-
def test_transform_none_to_type(self):
467-
# GH34377
468-
df = pd.DataFrame({"a": [None]})
469-
470-
msg = "DataFrame constructor called with incompatible data and dtype"
471-
with pytest.raises(TypeError, match=msg):
472-
df.transform({"a": int})
473-
474445

475446
class TestSeriesMap:
476447
def test_map(self, datetime_series):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import numpy as np
2+
import pytest
3+
4+
import pandas as pd
5+
import pandas._testing as tm
6+
7+
8+
def test_transform(string_series):
9+
# transforming functions
10+
11+
with np.errstate(all="ignore"):
12+
f_sqrt = np.sqrt(string_series)
13+
f_abs = np.abs(string_series)
14+
15+
# ufunc
16+
result = string_series.transform(np.sqrt)
17+
expected = f_sqrt.copy()
18+
tm.assert_series_equal(result, expected)
19+
20+
# list-like
21+
result = string_series.transform([np.sqrt])
22+
expected = f_sqrt.to_frame().copy()
23+
expected.columns = ["sqrt"]
24+
tm.assert_frame_equal(result, expected)
25+
26+
result = string_series.transform([np.sqrt])
27+
tm.assert_frame_equal(result, expected)
28+
29+
result = string_series.transform(["sqrt"])
30+
tm.assert_frame_equal(result, expected)
31+
32+
# multiple items in list
33+
# these are in the order as if we are applying both functions per
34+
# series and then concatting
35+
expected = pd.concat([f_sqrt, f_abs], axis=1)
36+
result = string_series.transform(["sqrt", "abs"])
37+
expected.columns = ["sqrt", "abs"]
38+
tm.assert_frame_equal(result, expected)
39+
40+
41+
def test_transform_and_agg_error(string_series):
42+
# we are trying to transform with an aggregator
43+
msg = "transforms cannot produce aggregated results"
44+
with pytest.raises(ValueError, match=msg):
45+
string_series.transform(["min", "max"])
46+
47+
msg = "cannot combine transform and aggregation operations"
48+
with pytest.raises(ValueError, match=msg):
49+
with np.errstate(all="ignore"):
50+
string_series.transform(["sqrt", "max"])
51+
52+
53+
def test_transform_none_to_type():
54+
# GH34377
55+
df = pd.DataFrame({"a": [None]})
56+
57+
msg = "DataFrame constructor called with incompatible data and dtype"
58+
with pytest.raises(TypeError, match=msg):
59+
df.transform({"a": int})

0 commit comments

Comments
 (0)