@@ -1103,3 +1103,70 @@ def test_transform_lambda_with_datetimetz():
1103
1103
name = "time" ,
1104
1104
)
1105
1105
tm .assert_series_equal (result , expected )
1106
+
1107
+
1108
+ def test_transform_fastpath_raises ():
1109
+ # GH#29631 case where fastpath defined in groupby.generic _choose_path
1110
+ # raises, but slow_path does not
1111
+
1112
+ df = pd .DataFrame ({"A" : [1 , 1 , 2 , 2 ], "B" : [1 , - 1 , 1 , 2 ]})
1113
+ gb = df .groupby ("A" )
1114
+
1115
+ def func (grp ):
1116
+ # we want a function such that func(frame) fails but func.apply(frame)
1117
+ # works
1118
+ if grp .ndim == 2 :
1119
+ # Ensure that fast_path fails
1120
+ raise NotImplementedError ("Don't cross the streams" )
1121
+ return grp * 2
1122
+
1123
+ # Check that the fastpath raises, see _transform_general
1124
+ obj = gb ._obj_with_exclusions
1125
+ gen = gb .grouper .get_iterator (obj , axis = gb .axis )
1126
+ fast_path , slow_path = gb ._define_paths (func )
1127
+ _ , group = next (gen )
1128
+
1129
+ with pytest .raises (NotImplementedError , match = "Don't cross the streams" ):
1130
+ fast_path (group )
1131
+
1132
+ result = gb .transform (func )
1133
+
1134
+ expected = pd .DataFrame ([2 , - 2 , 2 , 4 ], columns = ["B" ])
1135
+ tm .assert_frame_equal (result , expected )
1136
+
1137
+
1138
+ def test_transform_lambda_indexing ():
1139
+ # GH 7883
1140
+ df = pd .DataFrame (
1141
+ {
1142
+ "A" : ["foo" , "bar" , "foo" , "bar" , "foo" , "flux" , "foo" , "flux" ],
1143
+ "B" : ["one" , "one" , "two" , "three" , "two" , "six" , "five" , "three" ],
1144
+ "C" : range (8 ),
1145
+ "D" : range (8 ),
1146
+ "E" : range (8 ),
1147
+ }
1148
+ )
1149
+ df = df .set_index (["A" , "B" ])
1150
+ df = df .sort_index ()
1151
+ result = df .groupby (level = "A" ).transform (lambda x : x .iloc [- 1 ])
1152
+ expected = DataFrame (
1153
+ {
1154
+ "C" : [3 , 3 , 7 , 7 , 4 , 4 , 4 , 4 ],
1155
+ "D" : [3 , 3 , 7 , 7 , 4 , 4 , 4 , 4 ],
1156
+ "E" : [3 , 3 , 7 , 7 , 4 , 4 , 4 , 4 ],
1157
+ },
1158
+ index = MultiIndex .from_tuples (
1159
+ [
1160
+ ("bar" , "one" ),
1161
+ ("bar" , "three" ),
1162
+ ("flux" , "six" ),
1163
+ ("flux" , "three" ),
1164
+ ("foo" , "five" ),
1165
+ ("foo" , "one" ),
1166
+ ("foo" , "two" ),
1167
+ ("foo" , "two" ),
1168
+ ],
1169
+ names = ["A" , "B" ],
1170
+ ),
1171
+ )
1172
+ tm .assert_frame_equal (result , expected )
0 commit comments