Skip to content

Commit 522e701

Browse files
committed
Merge branch 'main' into ref-gpr_index
2 parents ced6479 + 0b0fa9b commit 522e701

File tree

18 files changed

+346
-189
lines changed

18 files changed

+346
-189
lines changed

Diff for: doc/source/whatsnew/v2.0.0.rst

+5
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,11 @@ Deprecations
780780
- :meth:`Index.is_object` has been deprecated. Use :func:`pandas.api.types.is_object_dtype` instead (:issue:`50042`)
781781
- :meth:`Index.is_interval` has been deprecated. Use :func:`pandas.api.types.is_intterval_dtype` instead (:issue:`50042`)
782782
- Deprecated ``all`` and ``any`` reductions with ``datetime64`` and :class:`DatetimeTZDtype` dtypes, use e.g. ``(obj != pd.Timestamp(0), tz=obj.tz).all()`` instead (:issue:`34479`)
783+
- Deprecated unused arguments ``*args`` and ``**kwargs`` in :class:`Resampler` (:issue:`50977`)
783784
- Deprecated calling ``float`` or ``int`` on a single element :class:`Series` to return a ``float`` or ``int`` respectively. Extract the element before calling ``float`` or ``int`` instead (:issue:`51101`)
785+
- Deprecated :meth:`Grouper.groups`, use :meth:`Groupby.groups` instead (:issue:`51182`)
786+
- Deprecated :meth:`Grouper.grouper`, use :meth:`Groupby.grouper` instead (:issue:`51182`)
787+
-
784788

785789
.. ---------------------------------------------------------------------------
786790
.. _whatsnew_200.prior_deprecations:
@@ -1196,6 +1200,7 @@ Indexing
11961200
- Bug in :meth:`Series.loc` raising error for out of bounds end of slice indexer (:issue:`50161`)
11971201
- Bug in :meth:`DataFrame.loc` raising ``ValueError`` with ``bool`` indexer and :class:`MultiIndex` (:issue:`47687`)
11981202
- Bug in :meth:`DataFrame.loc` raising ``IndexError`` when setting values for a pyarrow-backed column with a non-scalar indexer (:issue:`50085`)
1203+
- Bug in :meth:`DataFrame.loc` modifying object when setting incompatible value with an empty indexer (:issue:`45981`)
11991204
- Bug in :meth:`DataFrame.__setitem__` raising ``ValueError`` when right hand side is :class:`DataFrame` with :class:`MultiIndex` columns (:issue:`49121`)
12001205
- Bug in :meth:`DataFrame.reindex` casting dtype to ``object`` when :class:`DataFrame` has single extension array column when re-indexing ``columns`` and ``index`` (:issue:`48190`)
12011206
- Bug in :meth:`DataFrame.iloc` raising ``IndexError`` when indexer is a :class:`Series` with numeric extension array dtype (:issue:`49521`)

Diff for: pandas/core/common.py

+12
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,18 @@ def is_null_slice(obj) -> bool:
316316
)
317317

318318

319+
def is_empty_slice(obj) -> bool:
320+
"""
321+
We have an empty slice, e.g. no values are selected.
322+
"""
323+
return (
324+
isinstance(obj, slice)
325+
and obj.start is not None
326+
and obj.stop is not None
327+
and obj.start == obj.stop
328+
)
329+
330+
319331
def is_true_slices(line) -> list[bool]:
320332
"""
321333
Find non-trivial slices in "line": return a list of booleans with same length.

Diff for: pandas/core/generic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8783,7 +8783,7 @@ def resample(
87838783

87848784
axis = self._get_axis_number(axis)
87858785
return get_resampler(
8786-
self,
8786+
cast("Series | DataFrame", self),
87878787
freq=rule,
87888788
label=label,
87898789
closed=closed,

Diff for: pandas/core/groupby/generic.py

+43-27
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
is_dict_like,
5959
is_integer_dtype,
6060
is_interval_dtype,
61+
is_numeric_dtype,
6162
is_scalar,
6263
)
6364
from pandas.core.dtypes.missing import (
@@ -172,9 +173,18 @@ def _wrap_agged_manager(self, mgr: Manager) -> Series:
172173
# NB: caller is responsible for setting ser.index
173174
return ser
174175

175-
def _get_data_to_aggregate(self) -> SingleManager:
176+
def _get_data_to_aggregate(
177+
self, *, numeric_only: bool = False, name: str | None = None
178+
) -> SingleManager:
176179
ser = self._selected_obj
177180
single = ser._mgr
181+
if numeric_only and not is_numeric_dtype(ser.dtype):
182+
# GH#41291 match Series behavior
183+
kwd_name = "numeric_only"
184+
raise TypeError(
185+
f"Cannot use {kwd_name}=True with "
186+
f"{type(self).__name__}.{name} and non-numeric dtypes."
187+
)
178188
return single
179189

180190
def _iterate_slices(self) -> Iterable[Series]:
@@ -380,10 +390,16 @@ def _wrap_applied_output(
380390
"""
381391
if len(values) == 0:
382392
# GH #6265
393+
if is_transform:
394+
# GH#47787 see test_group_on_empty_multiindex
395+
res_index = data.index
396+
else:
397+
res_index = self.grouper.result_index
398+
383399
return self.obj._constructor(
384400
[],
385401
name=self.obj.name,
386-
index=self.grouper.result_index,
402+
index=res_index,
387403
dtype=data.dtype,
388404
)
389405
assert values is not None
@@ -1136,14 +1152,12 @@ def cov(
11361152
@property
11371153
@doc(Series.is_monotonic_increasing.__doc__)
11381154
def is_monotonic_increasing(self) -> Series:
1139-
result = self._op_via_apply("is_monotonic_increasing")
1140-
return result
1155+
return self.apply(lambda ser: ser.is_monotonic_increasing)
11411156

11421157
@property
11431158
@doc(Series.is_monotonic_decreasing.__doc__)
11441159
def is_monotonic_decreasing(self) -> Series:
1145-
result = self._op_via_apply("is_monotonic_decreasing")
1146-
return result
1160+
return self.apply(lambda ser: ser.is_monotonic_decreasing)
11471161

11481162
@doc(Series.hist.__doc__)
11491163
def hist(
@@ -1181,8 +1195,7 @@ def hist(
11811195
@property
11821196
@doc(Series.dtype.__doc__)
11831197
def dtype(self) -> Series:
1184-
result = self._op_via_apply("dtype")
1185-
return result
1198+
return self.apply(lambda ser: ser.dtype)
11861199

11871200
@doc(Series.unique.__doc__)
11881201
def unique(self) -> Series:
@@ -1428,9 +1441,13 @@ def _wrap_applied_output(
14281441
):
14291442

14301443
if len(values) == 0:
1431-
result = self.obj._constructor(
1432-
index=self.grouper.result_index, columns=data.columns
1433-
)
1444+
if is_transform:
1445+
# GH#47787 see test_group_on_empty_multiindex
1446+
res_index = data.index
1447+
else:
1448+
res_index = self.grouper.result_index
1449+
1450+
result = self.obj._constructor(index=res_index, columns=data.columns)
14341451
result = result.astype(data.dtypes, copy=False)
14351452
return result
14361453

@@ -1542,9 +1559,9 @@ def _cython_transform(
15421559
# test_transform_numeric_ret
15431560
# With self.axis == 1, _get_data_to_aggregate does a transpose
15441561
# so we always have a single block.
1545-
mgr: Manager2D = self._get_data_to_aggregate()
1546-
if numeric_only:
1547-
mgr = mgr.get_numeric_data(copy=False)
1562+
mgr: Manager2D = self._get_data_to_aggregate(
1563+
numeric_only=numeric_only, name=how
1564+
)
15481565

15491566
def arr_func(bvalues: ArrayLike) -> ArrayLike:
15501567
return self.grouper._cython_operation(
@@ -1719,18 +1736,11 @@ def _transform_item_by_item(self, obj: DataFrame, wrapper) -> DataFrame:
17191736
# iterate through columns, see test_transform_exclude_nuisance
17201737
# gets here with non-unique columns
17211738
output = {}
1722-
inds = []
17231739
for i, (colname, sgb) in enumerate(self._iterate_column_groupbys(obj)):
17241740
output[i] = sgb.transform(wrapper)
1725-
inds.append(i)
1726-
1727-
if not output:
1728-
raise TypeError("Transform function invalid for data types")
1729-
1730-
columns = obj.columns.take(inds)
17311741

17321742
result = self.obj._constructor(output, index=obj.index)
1733-
result.columns = columns
1743+
result.columns = obj.columns
17341744
return result
17351745

17361746
def filter(self, func, dropna: bool = True, *args, **kwargs):
@@ -1864,12 +1874,18 @@ def _gotitem(self, key, ndim: int, subset=None):
18641874

18651875
raise AssertionError("invalid ndim for _gotitem")
18661876

1867-
def _get_data_to_aggregate(self) -> Manager2D:
1877+
def _get_data_to_aggregate(
1878+
self, *, numeric_only: bool = False, name: str | None = None
1879+
) -> Manager2D:
18681880
obj = self._obj_with_exclusions
18691881
if self.axis == 1:
1870-
return obj.T._mgr
1882+
mgr = obj.T._mgr
18711883
else:
1872-
return obj._mgr
1884+
mgr = obj._mgr
1885+
1886+
if numeric_only:
1887+
mgr = mgr.get_numeric_data(copy=False)
1888+
return mgr
18731889

18741890
def _indexed_output_to_ndframe(
18751891
self, output: Mapping[base.OutputKey, ArrayLike]
@@ -2677,8 +2693,8 @@ def hist(
26772693
@property
26782694
@doc(DataFrame.dtypes.__doc__)
26792695
def dtypes(self) -> Series:
2680-
result = self._op_via_apply("dtypes")
2681-
return result
2696+
# error: Incompatible return value type (got "DataFrame", expected "Series")
2697+
return self.apply(lambda df: df.dtypes) # type: ignore[return-value]
26822698

26832699
@doc(DataFrame.corrwith.__doc__)
26842700
def corrwith(

0 commit comments

Comments
 (0)