Repository: pandas-dev/pandas

Issue:
BUG: nth on series groupby with dropna=True gives TypeError
From the docs: http://pandas-docs.github.io/pandas-docs-travis/groupby.html#taking-the-nth-row-of-each-group

```
In [1]: df = DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B'])

In [2]: g = df.groupby('A')

In [3]: g.B.nth(0, dropna=True)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-bcb9dcbefdf5> in <module>()
----> 1 g.B.nth(0, dropna=True)

C:\Users\vdbosscj\Scipy\pandas-joris\pandas\core\groupby.py in nth(self, n, drop
na)
    831         # get a new grouper for our dropped obj
    832         grouper, exclusions, obj = _get_grouper(dropped, key=self.keys,
axis=self.axis,
--> 833                                                 level=self.level, sort=s
elf.sort)
    834
    835         sizes = obj.groupby(grouper).size()

C:\Users\vdbosscj\Scipy\pandas-joris\pandas\core\groupby.py in _get_grouper(obj,
 key, axis, level, sort)
   2035             raise AssertionError(errmsg)
   2036
-> 2037         ping = Grouping(group_axis, gpr, obj=obj, name=name, level=level
, sort=sort)
   2038         groupings.append(ping)
   2039

C:\Users\vdbosscj\Scipy\pandas-joris\pandas\core\groupby.py in __init__(self, in
dex, grouper, obj, name, level, sort)
   1874             # no level passed
   1875             if not isinstance(self.grouper, (Series, np.ndarray)):
-> 1876                 self.grouper = self.index.map(self.grouper)
   1877                 if not (hasattr(self.grouper, "__len__") and
   1878                         len(self.grouper) == len(self.index)):

C:\Users\vdbosscj\Scipy\pandas-joris\pandas\core\index.py in map(self, mapper)
   1332
   1333     def map(self, mapper):
-> 1334         return self._arrmap(self.values, mapper)
   1335
   1336     def isin(self, values):

C:\Users\vdbosscj\Scipy\pandas-joris\pandas\algos.pyd in pandas.algos.arrmap_int
64 (pandas\algos.c:72351)()

TypeError: 'NoneType' object is not callable
```



Discussion:
related #7580 


Resolving patch:
diff --git a/pandas/core/groupby.py b/pandas/core/groupby.py
--- a/pandas/core/groupby.py
+++ b/pandas/core/groupby.py
@@ -829,11 +829,21 @@ def nth(self, n, dropna=None):
         dropped = self.obj.dropna(how=dropna, axis=self.axis)
 
         # get a new grouper for our dropped obj
-        grouper, exclusions, obj = _get_grouper(dropped, key=self.keys, axis=self.axis,
-                                                level=self.level, sort=self.sort)
+        if self.keys is None and self.level is None:
 
-        sizes = obj.groupby(grouper).size()
-        result = obj.groupby(grouper).nth(n)
+            # we don't have the grouper info available (e.g. we have selected out
+            # a column that is not in the current object)
+            axis = self.grouper.axis
+            grouper = axis[axis.isin(dropped.index)]
+            keys = self.grouper.names
+        else:
+
+            # create a grouper with the original parameters, but on the dropped object
+            grouper, _, _ = _get_grouper(dropped, key=self.keys, axis=self.axis,
+                                         level=self.level, sort=self.sort)
+
+        sizes = dropped.groupby(grouper).size()
+        result = dropped.groupby(grouper).nth(n)
         mask = (sizes<max_len).values
 
         # set the results which don't meet the criteria
@@ -841,7 +851,7 @@ def nth(self, n, dropna=None):
             result.loc[mask] = np.nan
 
         # reset/reindex to the original groups
-        if len(self.obj) == len(dropped):
+        if len(self.obj) == len(dropped) or len(result) == len(self.grouper.result_index):
             result.index = self.grouper.result_index
         else:
             result = result.reindex(self.grouper.result_index)


Test patch:
diff --git a/pandas/tests/test_groupby.py b/pandas/tests/test_groupby.py
--- a/pandas/tests/test_groupby.py
+++ b/pandas/tests/test_groupby.py
@@ -304,6 +304,13 @@ def test_nth(self):
         result = s.groupby(g).nth(0,dropna='all')
         assert_series_equal(result,expected)
 
+        # doc example
+        df = DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B'])
+        g = df.groupby('A')
+        result = g.B.nth(0, dropna=True)
+        expected = g.B.first()
+        assert_series_equal(result,expected)
+
     def test_grouper_index_types(self):
         # related GH5375
         # groupby misbehaving when using a Floatlike index