@@ -168,6 +168,10 @@ def test_transform_axis_1(request, transformation_func):
168168 # TODO(2.0) Remove after pad/backfill deprecation enforced
169169 transformation_func = maybe_normalize_deprecated_kernels (transformation_func )
170170
171+ if transformation_func == "ngroup" :
172+ msg = "ngroup fails with axis=1: #45986"
173+ request .node .add_marker (pytest .mark .xfail (reason = msg ))
174+
171175 warn = None
172176 if transformation_func == "tshift" :
173177 warn = FutureWarning
@@ -383,6 +387,15 @@ def test_transform_transformation_func(request, transformation_func):
383387 elif transformation_func == "fillna" :
384388 test_op = lambda x : x .transform ("fillna" , value = 0 )
385389 mock_op = lambda x : x .fillna (value = 0 )
390+ elif transformation_func == "ngroup" :
391+ test_op = lambda x : x .transform ("ngroup" )
392+ counter = - 1
393+
394+ def mock_op (x ):
395+ nonlocal counter
396+ counter += 1
397+ return Series (counter , index = x .index )
398+
386399 elif transformation_func == "tshift" :
387400 msg = (
388401 "Current behavior of groupby.tshift is inconsistent with other "
@@ -394,10 +407,14 @@ def test_transform_transformation_func(request, transformation_func):
394407 mock_op = lambda x : getattr (x , transformation_func )()
395408
396409 result = test_op (df .groupby ("A" ))
397- groups = [df [["B" ]].iloc [:4 ], df [["B" ]].iloc [4 :6 ], df [["B" ]].iloc [6 :]]
398- expected = concat ([mock_op (g ) for g in groups ])
410+ # pass the group in same order as iterating `for ... in df.groupby(...)`
411+ # but reorder to match df's index since this is a transform
412+ groups = [df [["B" ]].iloc [4 :6 ], df [["B" ]].iloc [6 :], df [["B" ]].iloc [:4 ]]
413+ expected = concat ([mock_op (g ) for g in groups ]).sort_index ()
414+ # sort_index does not preserve the freq
415+ expected = expected .set_axis (df .index )
399416
400- if transformation_func == "cumcount" :
417+ if transformation_func in ( "cumcount" , "ngroup" ) :
401418 tm .assert_series_equal (result , expected )
402419 else :
403420 tm .assert_frame_equal (result , expected )
@@ -1122,10 +1139,6 @@ def test_transform_agg_by_name(request, reduction_func, obj):
11221139 func = reduction_func
11231140 g = obj .groupby (np .repeat ([0 , 1 ], 3 ))
11241141
1125- if func == "ngroup" : # GH#27468
1126- request .node .add_marker (
1127- pytest .mark .xfail (reason = "TODO: g.transform('ngroup') doesn't work" )
1128- )
11291142 if func == "corrwith" and isinstance (obj , Series ): # GH#32293
11301143 request .node .add_marker (
11311144 pytest .mark .xfail (reason = "TODO: implement SeriesGroupBy.corrwith" )
@@ -1137,8 +1150,8 @@ def test_transform_agg_by_name(request, reduction_func, obj):
11371150 # this is the *definition* of a transformation
11381151 tm .assert_index_equal (result .index , obj .index )
11391152
1140- if func != " size" and obj .ndim == 2 :
1141- # size returns a Series, unlike other transforms
1153+ if func not in ( "ngroup" , " size") and obj .ndim == 2 :
1154+ # size/ngroup return a Series, unlike other transforms
11421155 tm .assert_index_equal (result .columns , obj .columns )
11431156
11441157 # verify that values were broadcasted across each group
@@ -1312,7 +1325,7 @@ def test_null_group_lambda_self(sort, dropna):
13121325
13131326def test_null_group_str_reducer (request , dropna , reduction_func ):
13141327 # GH 17093
1315- if reduction_func in ( "corrwith" , "ngroup" ) :
1328+ if reduction_func == "corrwith" :
13161329 msg = "incorrectly raises"
13171330 request .node .add_marker (pytest .mark .xfail (reason = msg ))
13181331 index = [1 , 2 , 3 , 4 ] # test transform preserves non-standard index
@@ -1358,31 +1371,11 @@ def test_null_group_str_reducer(request, dropna, reduction_func):
13581371
13591372
13601373@pytest .mark .filterwarnings ("ignore:tshift is deprecated:FutureWarning" )
1361- def test_null_group_str_transformer (
1362- request , using_array_manager , dropna , transformation_func
1363- ):
1374+ def test_null_group_str_transformer (request , dropna , transformation_func ):
13641375 # GH 17093
1365- xfails_block = (
1366- "cummax" ,
1367- "cummin" ,
1368- "cumsum" ,
1369- "fillna" ,
1370- "rank" ,
1371- "backfill" ,
1372- "ffill" ,
1373- "bfill" ,
1374- "pad" ,
1375- )
1376- xfails_array = ("cummax" , "cummin" , "cumsum" , "fillna" , "rank" )
13771376 if transformation_func == "tshift" :
13781377 msg = "tshift requires timeseries"
13791378 request .node .add_marker (pytest .mark .xfail (reason = msg ))
1380- elif dropna and (
1381- (not using_array_manager and transformation_func in xfails_block )
1382- or (using_array_manager and transformation_func in xfails_array )
1383- ):
1384- msg = "produces incorrect results when nans are present"
1385- request .node .add_marker (pytest .mark .xfail (reason = msg ))
13861379 args = (0 ,) if transformation_func == "fillna" else ()
13871380 df = DataFrame ({"A" : [1 , 1 , np .nan ], "B" : [1 , 2 , 2 ]}, index = [1 , 2 , 3 ])
13881381 gb = df .groupby ("A" , dropna = dropna )
@@ -1420,10 +1413,6 @@ def test_null_group_str_reducer_series(request, dropna, reduction_func):
14201413 msg = "corrwith not implemented for SeriesGroupBy"
14211414 request .node .add_marker (pytest .mark .xfail (reason = msg ))
14221415
1423- if reduction_func == "ngroup" :
1424- msg = "ngroup fails"
1425- request .node .add_marker (pytest .mark .xfail (reason = msg ))
1426-
14271416 # GH 17093
14281417 index = [1 , 2 , 3 , 4 ] # test transform preserves non-standard index
14291418 ser = Series ([1 , 2 , 2 , 3 ], index = index )
@@ -1470,15 +1459,6 @@ def test_null_group_str_transformer_series(request, dropna, transformation_func)
14701459 if transformation_func == "tshift" :
14711460 msg = "tshift requires timeseries"
14721461 request .node .add_marker (pytest .mark .xfail (reason = msg ))
1473- elif dropna and transformation_func in (
1474- "cummax" ,
1475- "cummin" ,
1476- "cumsum" ,
1477- "fillna" ,
1478- "rank" ,
1479- ):
1480- msg = "produces incorrect results when nans are present"
1481- request .node .add_marker (pytest .mark .xfail (reason = msg ))
14821462 args = (0 ,) if transformation_func == "fillna" else ()
14831463 ser = Series ([1 , 2 , 2 ], index = [1 , 2 , 3 ])
14841464 gb = ser .groupby ([1 , 1 , np .nan ], dropna = dropna )
@@ -1502,4 +1482,10 @@ def test_null_group_str_transformer_series(request, dropna, transformation_func)
15021482 msg = f"{ transformation_func } is deprecated"
15031483 with tm .assert_produces_warning (warn , match = msg ):
15041484 result = gb .transform (transformation_func , * args )
1505- tm .assert_equal (result , expected )
1485+ if dropna and transformation_func == "fillna" :
1486+ # GH#46369 - result name is the group; remove this block when fixed.
1487+ tm .assert_equal (result , expected , check_names = False )
1488+ # This should be None
1489+ assert result .name == 1.0
1490+ else :
1491+ tm .assert_equal (result , expected )
0 commit comments