Skip to content

Commit 3de9137

Browse files
rbenesjreback
authored andcommitted
Bug groupby idxmin (#25531)
1 parent e1aa6f3 commit 3de9137

File tree

5 files changed

+48
-3
lines changed

5 files changed

+48
-3
lines changed

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ Groupby/Resample/Rolling
372372
- Bug in :func:`pandas.core.groupby.GroupBy.agg` when applying a aggregation function to timezone aware data (:issue:`23683`)
373373
- Bug in :func:`pandas.core.groupby.GroupBy.first` and :func:`pandas.core.groupby.GroupBy.last` where timezone information would be dropped (:issue:`21603`)
374374
- Ensured that ordering of outputs in ``groupby`` aggregation functions is consistent across all versions of Python (:issue:`25692`)
375+
- Bug in :func:`idxmax` and :func:`idxmin` on :meth:`DataFrame.groupby` with datetime column would return incorrect dtype (:issue:`25444`, :issue:`15306`)
375376

376377

377378
Reshaping

pandas/core/groupby/base.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ def _gotitem(self, key, ndim, subset=None):
8989
cython_transforms = frozenset(['cumprod', 'cumsum', 'shift',
9090
'cummin', 'cummax'])
9191

92-
cython_cast_blacklist = frozenset(['rank', 'count', 'size'])
92+
cython_cast_blacklist = frozenset(['rank', 'count', 'size', 'idxmin',
93+
'idxmax'])
9394

9495

9596
def whitelist_method_generator(base, klass, whitelist):

pandas/core/groupby/generic.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,13 @@ def _aggregate_item_by_item(self, func, *args, **kwargs):
261261
data = obj[item]
262262
colg = SeriesGroupBy(data, selection=item,
263263
grouper=self.grouper)
264-
result[item] = self._try_cast(
265-
colg.aggregate(func, *args, **kwargs), data)
264+
265+
cast = self._transform_should_cast(func)
266+
267+
result[item] = colg.aggregate(func, *args, **kwargs)
268+
if cast:
269+
result[item] = self._try_cast(result[item], data)
270+
266271
except ValueError:
267272
cannot_agg.append(item)
268273
continue

pandas/tests/groupby/test_function.py

+19
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,25 @@ def test_groupby_non_arithmetic_agg_int_like_precision(i):
400400
assert res.iloc[0].b == data["expected"]
401401

402402

403+
@pytest.mark.parametrize("func, values", [
404+
("idxmin", {'c_int': [0, 2], 'c_float': [1, 3], 'c_date': [1, 2]}),
405+
("idxmax", {'c_int': [1, 3], 'c_float': [0, 2], 'c_date': [0, 3]})
406+
])
407+
def test_idxmin_idxmax_returns_int_types(func, values):
408+
# GH 25444
409+
df = pd.DataFrame({'name': ['A', 'A', 'B', 'B'],
410+
'c_int': [1, 2, 3, 4],
411+
'c_float': [4.02, 3.03, 2.04, 1.05],
412+
'c_date': ['2019', '2018', '2016', '2017']})
413+
df['c_date'] = pd.to_datetime(df['c_date'])
414+
415+
result = getattr(df.groupby('name'), func)()
416+
417+
expected = pd.DataFrame(values, index=Index(['A', 'B'], name="name"))
418+
419+
tm.assert_frame_equal(result, expected)
420+
421+
403422
def test_fill_consistency():
404423

405424
# GH9221

pandas/tests/groupby/test_transform.py

+19
Original file line numberDiff line numberDiff line change
@@ -844,3 +844,22 @@ def test_groupby_transform_timezone_column(func):
844844
expected = pd.DataFrame([[ts, 1, ts]], columns=['end_time', 'id',
845845
'max_end_time'])
846846
tm.assert_frame_equal(result, expected)
847+
848+
849+
@pytest.mark.parametrize("func, values", [
850+
("idxmin", ["1/1/2011"] * 2 + ["1/3/2011"] * 7 + ["1/10/2011"]),
851+
("idxmax", ["1/2/2011"] * 2 + ["1/9/2011"] * 7 + ["1/10/2011"])
852+
])
853+
def test_groupby_transform_with_datetimes(func, values):
854+
# GH 15306
855+
dates = pd.date_range('1/1/2011', periods=10, freq='D')
856+
857+
stocks = pd.DataFrame({'price': np.arange(10.0)}, index=dates)
858+
stocks['week_id'] = pd.to_datetime(stocks.index).week
859+
860+
result = stocks.groupby(stocks['week_id'])['price'].transform(func)
861+
862+
expected = pd.Series(data=pd.to_datetime(values),
863+
index=dates, name="price")
864+
865+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)