{"action":"closed","issue":{"url":"https://api.github.com/repos/pydata/pandas/issues/11742","repository_url":"https://api.github.com/repos/pydata/pandas","labels_url":"https://api.github.com/repos/pydata/pandas/issues/11742/labels{/name}","comments_url":"https://api.github.com/repos/pydata/pandas/issues/11742/comments","events_url":"https://api.github.com/repos/pydata/pandas/issues/11742/events","html_url":"https://github.com/pydata/pandas/issues/11742","id":119986863,"number":11742,"title":"Inconsistent return type when grouping dates by frequency with custom reduction function","user":{"login":"stephen-hoover","id":8355977,"avatar_url":"https://avatars.githubusercontent.com/u/8355977?v=3","gravatar_id":"","url":"https://api.github.com/users/stephen-hoover","html_url":"https://github.com/stephen-hoover","followers_url":"https://api.github.com/users/stephen-hoover/followers","following_url":"https://api.github.com/users/stephen-hoover/following{/other_user}","gists_url":"https://api.github.com/users/stephen-hoover/gists{/gist_id}","starred_url":"https://api.github.com/users/stephen-hoover/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephen-hoover/subscriptions","organizations_url":"https://api.github.com/users/stephen-hoover/orgs","repos_url":"https://api.github.com/users/stephen-hoover/repos","events_url":"https://api.github.com/users/stephen-hoover/events{/privacy}","received_events_url":"https://api.github.com/users/stephen-hoover/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/pydata/pandas/labels/API%20Design","name":"API Design","color":"AD7FA8"},{"url":"https://api.github.com/repos/pydata/pandas/labels/Difficulty%20Advanced","name":"Difficulty Advanced","color":"fbca04"},{"url":"https://api.github.com/repos/pydata/pandas/labels/Dtypes","name":"Dtypes","color":"e102d8"},{"url":"https://api.github.com/repos/pydata/pandas/labels/Effort%20Medium","name":"Effort Medium","color":"006b75"},{"url":"https://api.github.com/repos/pydata/pandas/labels/Groupby","name":"Groupby","color":"729FCF"},{"url":"https://api.github.com/repos/pydata/pandas/labels/Resample","name":"Resample","color":"207de5"}],"state":"closed","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/pydata/pandas/milestones/38","html_url":"https://github.com/pydata/pandas/milestones/0.18.1","labels_url":"https://api.github.com/repos/pydata/pandas/milestones/38/labels","id":1570594,"number":38,"title":"0.18.1","description":"after 0.18.0 of course!","creator":{"login":"jreback","id":953992,"avatar_url":"https://avatars.githubusercontent.com/u/953992?v=3","gravatar_id":"","url":"https://api.github.com/users/jreback","html_url":"https://github.com/jreback","followers_url":"https://api.github.com/users/jreback/followers","following_url":"https://api.github.com/users/jreback/following{/other_user}","gists_url":"https://api.github.com/users/jreback/gists{/gist_id}","starred_url":"https://api.github.com/users/jreback/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jreback/subscriptions","organizations_url":"https://api.github.com/users/jreback/orgs","repos_url":"https://api.github.com/users/jreback/repos","events_url":"https://api.github.com/users/jreback/events{/privacy}","received_events_url":"https://api.github.com/users/jreback/received_events","type":"User","site_admin":false},"open_issues":178,"closed_issues":77,"state":"open","created_at":"2016-02-08T15:29:59Z","updated_at":"2016-04-01T13:13:27Z","due_on":"2016-04-26T04:00:00Z","closed_at":null},"comments":3,"created_at":"2015-12-02T16:53:20Z","updated_at":"2016-04-01T13:13:27Z","closed_at":"2016-04-01T13:13:27Z","body":"If I group a `DataFrame` by a column of dates, the return type varies depending on whether I just group or whether I also apply a frequency in the `Grouper`. \r\n\r\nGrouping without resampling dates returns a `DataFrame` when I apply a function which returns a labeled `Series`, or a `Series` if the function returns a scalar:\r\n```\r\nIn [1]: import pandas as pd\r\n\r\nIn [2]: df = pd.DataFrame({'date': ['10/10/2000', '11/10/2000'], 'value': [10, 13]})\r\n\r\nIn [3]: def sumfunc(x):\r\n   ...:     return pd.Series([x['value'].sum()], ('sum',))\r\n   ...: \r\n\r\nIn [4]: df.groupby(pd.Grouper(key='date')).apply(sumfunc)\r\nOut[4]: \r\n            sum\r\ndate           \r\n10/10/2000   10\r\n11/10/2000   13\r\n\r\nIn [5]: type(df.groupby(pd.Grouper(key='date')).apply(sumfunc))\r\nOut[5]: pandas.core.frame.DataFrame\r\n\r\nIn [17]: df.groupby(pd.Grouper(key='date')).apply(lambda x: x.value.sum())\r\nOut[17]: \r\ndate\r\n2000-10-10    10\r\n2000-11-10    13\r\ndtype: int64\r\n\r\nIn [18]: type(df.groupby(pd.Grouper(key='date')).apply(lambda x: x.value.sum()))\r\nOut[18]: pandas.core.series.Series\r\n```\r\n\r\nIf I apply a frequency in the `Grouper`, I get a `Series` with a multi-index when the function returns a labeled `Series`, or a `TypeError` when it returns a scalar.\r\n```\r\nIn [6]: df['date'] = pd.to_datetime(df['date'])\r\n\r\nIn [7]: df.groupby(pd.Grouper(freq='M', key='date')).apply(sumfunc)\r\nOut[7]: \r\ndate           \r\n2000-10-31  sum    10\r\n2000-11-30  sum    13\r\ndtype: int64\r\n\r\nIn [8]: type(df.groupby(pd.Grouper(freq='M', key='date')).apply(sumfunc))\r\nOut[8]: pandas.core.series.Series\r\n\r\nIn [16]: df.groupby(pd.Grouper(freq='M', key='date')).apply(lambda x: x.value.sum())\r\n---------------------------------------------------------------------------\r\nTypeError                                 Traceback (most recent call last)\r\n<ipython-input-16-ad73d0ebc475> in <module>()\r\n----> 1 df.groupby(pd.Grouper(freq='M', key='date')).apply(lambda x: x.value.sum())\r\n\r\n/Users/shoover/.py35/lib/python3.5/site-packages/pandas/core/groupby.py in apply(self, func, *args, **kwargs)\r\n    713         # ignore SettingWithCopy here in case the user mutates\r\n    714         with option_context('mode.chained_assignment',None):\r\n--> 715             return self._python_apply_general(f)\r\n    716 \r\n    717     def _python_apply_general(self, f):\r\n\r\n/Users/shoover/.py35/lib/python3.5/site-packages/pandas/core/groupby.py in _python_apply_general(self, f)\r\n    720 \r\n    721         return self._wrap_applied_output(keys, values,\r\n--> 722                                          not_indexed_same=mutated)\r\n    723 \r\n    724     def aggregate(self, func, *args, **kwargs):\r\n\r\n/Users/shoover/.py35/lib/python3.5/site-packages/pandas/core/groupby.py in _wrap_applied_output(self, keys, values, not_indexed_same)\r\n   3253             # Handle cases like BinGrouper\r\n   3254             return self._concat_objects(keys, values,\r\n-> 3255                                         not_indexed_same=not_indexed_same)\r\n   3256 \r\n   3257     def _transform_general(self, func, *args, **kwargs):\r\n\r\n/Users/shoover/.py35/lib/python3.5/site-packages/pandas/core/groupby.py in _concat_objects(self, keys, values, not_indexed_same)\r\n   1271                 group_names = self.grouper.names\r\n   1272                 result = concat(values, axis=self.axis, keys=group_keys,\r\n-> 1273                                 levels=group_levels, names=group_names)\r\n   1274             else:\r\n   1275 \r\n\r\n/Users/shoover/.py35/lib/python3.5/site-packages/pandas/tools/merge.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, copy)\r\n    810                        keys=keys, levels=levels, names=names,\r\n    811                        verify_integrity=verify_integrity,\r\n--> 812                        copy=copy)\r\n    813     return op.get_result()\r\n    814 \r\n\r\n/Users/shoover/.py35/lib/python3.5/site-packages/pandas/tools/merge.py in __init__(self, objs, axis, join, join_axes, keys, levels, names, ignore_index, verify_integrity, copy)\r\n    866         for obj in objs:\r\n    867             if not isinstance(obj, NDFrame):\r\n--> 868                 raise TypeError(\"cannot concatenate a non-NDFrame object\")\r\n    869 \r\n    870             # consolidate\r\n\r\nTypeError: cannot concatenate a non-NDFrame object\r\n```\r\n\r\nSince in this example, assigning dates to months still leaves the same groups, I would have expected identical results whether I set `freq='M'` or not. I'm guessing that the difference is that the `freq='M'` causes an extra `groupby` to happen under the hood, yes? When I ran into this, what I expected to happen was for `pd.Grouper(freq='M', key='date')` to do a single `groupby`, combining rows where dates happened to fall into the same month.\r\n\r\nPandas version:\r\n```\r\nIn [9]: pd.__version__\r\nOut[9]: '0.17.1+22.g0c43fcc'\r\n```"}}