# Buggy code
def nunique(self, dropna=True):
    """Returns number of unique elements in the group"""
    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 boundaries 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,
    )


# Traceback (ValueError)
Traceback (most recent call last):
File "test.py", line 6, in <module>
tmp.groupby(pd.TimeGrouper('D')).ID.nunique()
File "/usr/lib/python3/dist-packages/pandas/core/groupby.py", line 2697, in nunique
name=self.name)
File "/usr/lib/python3/dist-packages/pandas/core/series.py", line 227, in __init__
data = SingleBlockManager(data, index, fastpath=True)
File "/usr/lib/python3/dist-packages/pandas/core/internals.py", line 3736, in __init__
ndim=1, fastpath=True)
File "/usr/lib/python3/dist-packages/pandas/core/internals.py", line 2454, in make_block
placement=placement)
File "/usr/lib/python3/dist-packages/pandas/core/internals.py", line 87, in __init__
len(self.values), len(self.mgr_locs)))
ValueError: Wrong number of items passed 2, placement implies 4

# Fixed code
def nunique(self, dropna=True):
    """Returns number of unique elements in the group"""
    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 boundaries 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)
    res = out if ids[0] != -1 else out[1:]
    ri = self.grouper.result_index

    # we might have duplications among the bins
    if len(res) != len(ri):
        res, out = np.zeros(len(ri), dtype=out.dtype), res
        res[ids] = out

    return Series(res, index=ri, name=self.name)