simple prototype of group by, with support for expressions in the group-by clause 
           and outputs
           @param keyexpr: grouping field and optional expression for computing the key value;
                if a string is passed
           @type keyexpr: string or tuple
           @param outexprs: named arguments describing one or more summary values to 
           compute per key
           @type outexprs: callable, taking a sequence of objects as input and returning
           a single summary value

def groupby(self, keyexpr, **outexprs):
        """simple prototype of group by, with support for expressions in the group-by clause 
           and outputs
           @param keyexpr: grouping field and optional expression for computing the key value;
                if a string is passed
           @type keyexpr: string or tuple
           @param outexprs: named arguments describing one or more summary values to 
           compute per key
           @type outexprs: callable, taking a sequence of objects as input and returning
           a single summary value
           """
        if isinstance(keyexpr, basestring):
            keyattrs = keyexpr.split()
            keyfn = lambda o: tuple(getattr(o, k) for k in keyattrs)

        elif isinstance(keyexpr, tuple):
            keyattrs = (keyexpr[0],)
            keyfn = keyexpr[1]

        else:
            raise TypeError("keyexpr must be string or tuple")

        groupedobs = defaultdict(list)
        do_all(groupedobs[keyfn(ob)].append(ob) for ob in self.obs)

        tbl = Table()
        do_all(tbl.create_index(k, unique=(len(keyattrs) == 1)) for k in keyattrs)
        for key, recs in sorted(groupedobs.items()):
            groupobj = DataObject(**dict(zip(keyattrs, key)))
            do_all(setattr(groupobj, subkey, expr(recs)) for subkey, expr in outexprs.items())
            tbl.insert(groupobj)
        return tbl