-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
BUG: Preserve Series/DataFrame subclasses through groupby operations #33884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 35 commits
7da0703
f6e1a89
ee6de43
3f9f4c4
0112826
422e702
53ac397
2bc2520
8d9a885
e4d7fa8
1dbe986
c998422
abdb861
d36ad6d
5b83062
b6ea731
0cdf0ea
6e48e07
a70c21a
c03d459
9e42c79
9fbc645
5750d72
7f4c5a7
8eee73c
4b304c1
b3e039a
b1118de
a490e38
5bcf9fa
0244b36
dcd4692
a92c51b
cf3b978
f08cf59
d2a7de2
37ea97f
f1570da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1182,6 +1182,16 @@ class GroupBy(_GroupBy[FrameOrSeries]): | |
more | ||
""" | ||
|
||
@property | ||
def _constructor(self) -> Type["Series"]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm this should be FrameOrSeries I think. why is there an else here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had thought this should be a Series because if The else was there because @property
def _series_constructor(self) -> Type["Series"]:
# GH28330 preserve subclassed Series/DataFrames
if isinstance(self.obj, DataFrame):
return self.obj._constructor_sliced
assert isinstance(self.obj, Series)
return self.obj._constructor Please let me know if you have a better way to structure this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes pls use an assertion maybe @simonjayhawkins or @WillAyd can help with the annotation itself There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks -- I changed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the annotation is correct given the way it is implemented, though I am not sure about the implementation. Why do we need to dispatch to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ends up being used in As such, the motivation for dispatching to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm that's unfortunate... Can you rename this property to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or maybe even There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah -- I think |
||
# GH28330 preserve subclassed Series/DataFrames | ||
if isinstance(self.obj, DataFrame): | ||
return self.obj._constructor_sliced | ||
elif isinstance(self.obj, Series): | ||
return self.obj._constructor | ||
else: | ||
return Series | ||
|
||
def _bool_agg(self, val_test, skipna): | ||
""" | ||
Shared func to call any / all Cython GroupBy implementations. | ||
|
@@ -1420,8 +1430,11 @@ def size(self): | |
""" | ||
result = self.grouper.size() | ||
|
||
if isinstance(self.obj, Series): | ||
result.name = self.obj.name | ||
# GH28330 preserve subclassed Series/DataFrames through calls | ||
if issubclass(self.obj._constructor, Series): | ||
result = self._constructor(result, name=self.obj.name) | ||
else: | ||
result = self._constructor(result) | ||
return self._reindex_output(result, fill_value=0) | ||
|
||
@classmethod | ||
|
@@ -2116,7 +2129,7 @@ def ngroup(self, ascending: bool = True): | |
""" | ||
with _group_selection_context(self): | ||
index = self._selected_obj.index | ||
result = Series(self.grouper.group_info[0], index) | ||
result = self._constructor(self.grouper.group_info[0], index) | ||
if not ascending: | ||
result = self.ngroups - 1 - result | ||
return result | ||
|
@@ -2178,7 +2191,7 @@ def cumcount(self, ascending: bool = True): | |
with _group_selection_context(self): | ||
index = self._selected_obj.index | ||
cumcounts = self._cumcount_array(ascending=ascending) | ||
return Series(cumcounts, index) | ||
return self._constructor(cumcounts, index) | ||
|
||
@Substitution(name="groupby") | ||
@Appender(_common_see_also) | ||
|
Uh oh!
There was an error while loading. Please reload this page.