# Buggy code
def nunique(self, dropna=True):
    ids, _, _ = self.grouper.group_info
    val = self.obj.get_values()

    try:
        sorter = np.lexsort((val, ids))
    except TypeError:  # catches object dtypes
        assert val.dtype == object, "val.dtype must be object, got %s" % val.dtype
        val, _ = algos.factorize(val, sort=False)
        sorter = np.lexsort((val, ids))
        isnull = lambda a: a == -1
    else:
        isnull = com.isnull

    ids, val = ids[sorter], val[sorter]

    # group boundries are where group ids change
    # unique observations are where sorted values change
    idx = com._ensure_int64(np.r_[0, 1 + np.nonzero(ids[1:] != ids[:-1])[0]])
    inc = com._ensure_int64(np.r_[1, val[1:] != val[:-1]])

    # 1st item of each group is a new unique observation
    mask = isnull(val)
    if dropna:
        inc[idx] = 1
        inc[mask] = 0
    else:
        inc[mask & np.r_[False, mask[:-1]]] = 0
        inc[idx] = 1

    out = np.add.reduceat(inc, idx)
    return Series(
        out if ids[0] != -1 else out[1:],
        index=self.grouper.result_index,
        name=self.name,
    )


# Traceback (TypeError)
In [1]: df = pd.DataFrame({"id":[1,2,3,4,5,6], "grade":['a', 'b', 'b', 'a', 'a', 'e']})

In [2]: df.groupby("grade").size()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-d8e387418f9d> in <module>()
----> 1 df.groupby("grade").size()

/home/joris/scipy/pandas/pandas/core/groupby.pyc in size(self)
818
819         """
--> 820         return self.grouper.size()
821
822     sum = _groupby_function('sum', 'add', np.sum)

/home/joris/scipy/pandas/pandas/core/groupby.pyc in size(self)
1380         """
1381         ids, _, ngroup = self.group_info
-> 1382         out = np.bincount(ids[ids != -1], minlength=ngroup)
1383         return Series(out, index=self.result_index)
1384

TypeError: Cannot cast array data from dtype('int64') to dtype('int32') according to the rule 'safe'

In [4]: pd.__version__
Out[4]: '0.17.0rc1+108.g3fb802a'

# Fixed code
def nunique(self, dropna=True):
    ids, _, _ = self.grouper.group_info
    val = self.obj.get_values()

    try:
        sorter = np.lexsort((val, ids))
    except TypeError:  # catches object dtypes
        assert val.dtype == object, "val.dtype must be object, got %s" % val.dtype
        val, _ = algos.factorize(val, sort=False)
        sorter = np.lexsort((val, ids))
        isnull = lambda a: a == -1
    else:
        isnull = com.isnull

    ids, val = ids[sorter], val[sorter]

    # group boundries are where group ids change
    # unique observations are where sorted values change
    idx = np.r_[0, 1 + np.nonzero(ids[1:] != ids[:-1])[0]]
    inc = np.r_[1, val[1:] != val[:-1]]

    # 1st item of each group is a new unique observation
    mask = isnull(val)
    if dropna:
        inc[idx] = 1
        inc[mask] = 0
    else:
        inc[mask & np.r_[False, mask[:-1]]] = 0
        inc[idx] = 1

    out = np.add.reduceat(inc, idx).astype("int64", copy=False)
    return Series(
        out if ids[0] != -1 else out[1:],
        index=self.grouper.result_index,
        name=self.name,
    )