28
28
29
29
from pandas ._libs import (
30
30
Interval ,
31
+ lib ,
31
32
reduction as libreduction ,
32
33
)
33
34
from pandas ._typing import (
@@ -1128,18 +1129,24 @@ def _wrap_applied_output_series(
1128
1129
return self ._reindex_output (result )
1129
1130
1130
1131
def _cython_transform (
1131
- self , how : str , numeric_only : bool = True , axis : int = 0 , ** kwargs
1132
+ self ,
1133
+ how : str ,
1134
+ numeric_only : bool | lib .NoDefault = lib .no_default ,
1135
+ axis : int = 0 ,
1136
+ ** kwargs ,
1132
1137
) -> DataFrame :
1133
1138
assert axis == 0 # handled by caller
1134
1139
# TODO: no tests with self.ndim == 1 for DataFrameGroupBy
1140
+ numeric_only_bool = self ._resolve_numeric_only (numeric_only , axis )
1135
1141
1136
1142
# With self.axis == 0, we have multi-block tests
1137
1143
# e.g. test_rank_min_int, test_cython_transform_frame
1138
1144
# test_transform_numeric_ret
1139
1145
# With self.axis == 1, _get_data_to_aggregate does a transpose
1140
1146
# so we always have a single block.
1141
1147
mgr : Manager2D = self ._get_data_to_aggregate ()
1142
- if numeric_only :
1148
+ orig_mgr_len = len (mgr )
1149
+ if numeric_only_bool :
1143
1150
mgr = mgr .get_numeric_data (copy = False )
1144
1151
1145
1152
def arr_func (bvalues : ArrayLike ) -> ArrayLike :
@@ -1152,8 +1159,8 @@ def arr_func(bvalues: ArrayLike) -> ArrayLike:
1152
1159
res_mgr = mgr .grouped_reduce (arr_func , ignore_failures = True )
1153
1160
res_mgr .set_axis (1 , mgr .axes [1 ])
1154
1161
1155
- if len (res_mgr ) < len ( mgr ) :
1156
- warn_dropping_nuisance_columns_deprecated (type (self ), how )
1162
+ if len (res_mgr ) < orig_mgr_len :
1163
+ warn_dropping_nuisance_columns_deprecated (type (self ), how , numeric_only )
1157
1164
1158
1165
res_df = self .obj ._constructor (res_mgr )
1159
1166
if self .axis == 1 :
@@ -1269,7 +1276,9 @@ def _transform_item_by_item(self, obj: DataFrame, wrapper) -> DataFrame:
1269
1276
output [i ] = sgb .transform (wrapper )
1270
1277
except TypeError :
1271
1278
# e.g. trying to call nanmean with string values
1272
- warn_dropping_nuisance_columns_deprecated (type (self ), "transform" )
1279
+ warn_dropping_nuisance_columns_deprecated (
1280
+ type (self ), "transform" , numeric_only = False
1281
+ )
1273
1282
else :
1274
1283
inds .append (i )
1275
1284
@@ -1559,53 +1568,73 @@ def nunique(self, dropna: bool = True) -> DataFrame:
1559
1568
_shared_docs ["idxmax" ],
1560
1569
numeric_only_default = "True for axis=0, False for axis=1" ,
1561
1570
)
1562
- def idxmax (self , axis = 0 , skipna : bool = True , numeric_only : bool | None = None ):
1571
+ def idxmax (
1572
+ self ,
1573
+ axis = 0 ,
1574
+ skipna : bool = True ,
1575
+ numeric_only : bool | lib .NoDefault = lib .no_default ,
1576
+ ):
1563
1577
axis = DataFrame ._get_axis_number (axis )
1564
- if numeric_only is None :
1565
- numeric_only = None if axis == 0 else False
1578
+ if numeric_only is lib .no_default :
1579
+ # Cannot use self._resolve_numeric_only; we must pass None to
1580
+ # DataFrame.idxmax for backwards compatibility
1581
+ numeric_only_arg = None if axis == 0 else False
1582
+ else :
1583
+ numeric_only_arg = cast (bool , numeric_only )
1566
1584
1567
1585
def func (df ):
1568
- # NB: here we use numeric_only=None, in DataFrame it is False GH#38217
1569
1586
res = df ._reduce (
1570
1587
nanops .nanargmax ,
1571
1588
"argmax" ,
1572
1589
axis = axis ,
1573
1590
skipna = skipna ,
1574
- numeric_only = numeric_only ,
1591
+ numeric_only = numeric_only_arg ,
1575
1592
)
1576
1593
indices = res ._values
1577
1594
index = df ._get_axis (axis )
1578
1595
result = [index [i ] if i >= 0 else np .nan for i in indices ]
1579
1596
return df ._constructor_sliced (result , index = res .index )
1580
1597
1581
1598
func .__name__ = "idxmax"
1582
- return self ._python_apply_general (func , self ._obj_with_exclusions )
1599
+ result = self ._python_apply_general (func , self ._obj_with_exclusions )
1600
+ self ._maybe_warn_numeric_only_depr ("idxmax" , result , numeric_only )
1601
+ return result
1583
1602
1584
1603
@doc (
1585
1604
_shared_docs ["idxmin" ],
1586
1605
numeric_only_default = "True for axis=0, False for axis=1" ,
1587
1606
)
1588
- def idxmin (self , axis = 0 , skipna : bool = True , numeric_only : bool | None = None ):
1607
+ def idxmin (
1608
+ self ,
1609
+ axis = 0 ,
1610
+ skipna : bool = True ,
1611
+ numeric_only : bool | lib .NoDefault = lib .no_default ,
1612
+ ):
1589
1613
axis = DataFrame ._get_axis_number (axis )
1590
- if numeric_only is None :
1591
- numeric_only = None if axis == 0 else False
1614
+ if numeric_only is lib .no_default :
1615
+ # Cannot use self._resolve_numeric_only; we must pass None to
1616
+ # DataFrame.idxmin for backwards compatibility
1617
+ numeric_only_arg = None if axis == 0 else False
1618
+ else :
1619
+ numeric_only_arg = cast (bool , numeric_only )
1592
1620
1593
1621
def func (df ):
1594
- # NB: here we use numeric_only=None, in DataFrame it is False GH#46560
1595
1622
res = df ._reduce (
1596
1623
nanops .nanargmin ,
1597
1624
"argmin" ,
1598
1625
axis = axis ,
1599
1626
skipna = skipna ,
1600
- numeric_only = numeric_only ,
1627
+ numeric_only = numeric_only_arg ,
1601
1628
)
1602
1629
indices = res ._values
1603
1630
index = df ._get_axis (axis )
1604
1631
result = [index [i ] if i >= 0 else np .nan for i in indices ]
1605
1632
return df ._constructor_sliced (result , index = res .index )
1606
1633
1607
1634
func .__name__ = "idxmin"
1608
- return self ._python_apply_general (func , self ._obj_with_exclusions )
1635
+ result = self ._python_apply_general (func , self ._obj_with_exclusions )
1636
+ self ._maybe_warn_numeric_only_depr ("idxmin" , result , numeric_only )
1637
+ return result
1609
1638
1610
1639
boxplot = boxplot_frame_groupby
1611
1640
0 commit comments