groupby can accept an index or list of indices as the key

The approach taken here is to move the core of the calculation to inline function `_groupby_core`.  This reduces the amount of repeated code while maintaining very high performance.  `reduceby` and `countby` will use a similar structure of branching and iteration.

In case there was any doubt, performing this optimization (instead of using a "getter" function) is most definitely worth it!