Group aggregate #1546

@taldcroft please have a look at the changes. Also here is a comparison of np.sum and np.add.reduceat.
![comparison](https://cloud.githubusercontent.com/assets/5782112/3280724/346b350a-f479-11e3-9f7f-d364b806d2b4.png)

```
This can improve the performance by a factor of 10 to 100 (or more) for large tables with many relatively small 
groups.  It also allows for the use of certain numpy functions which normally take more than one input array but also
 work as reduction functions, like `numpy.add`.  The numpy functions which should take advantage of using 
`numpy.ufunc.reduceat` include:

`numpy.add`, `numpy.arctan2`, `numpy.bitwise_and`, `numpy.bitwise_or`, `numpy.bitwise_xor`, `numpy.copysign`,
 `numpy.divide`, `numpy.equal`, `numpy.floor_divide`, `numpy.fmax`, `numpy.fmin`, `numpy.fmod`,
 `numpy.greater_equal`, `numpy.greater`, `numpy.hypot`, `numpy.left_shift`, `numpy.less_equal`, `numpy.less`,
 `numpy.logaddexp2`, `numpy.logaddexp`, `numpy.logical_and`, `numpy.logical_or`, `numpy.logical_xor`,
 `numpy.maximum`, `numpy.minimum`, `numpy.mod`, `numpy.multiply`, `numpy.nextafter`, `numpy.not_equal`,
 `numpy.power`, `numpy.remainder`, `numpy.right_shift`, `numpy.subtract`,  and `numpy.true_divide`.

As special cases ...
```

I used the following code to find out this list:
```
x = np.arange(10)
indices = np.array([0, 5])
names = []
for name, func in vars(np).items():
    if not hasattr(func, 'reduceat'):
        continue
    try:
        out = func.reduceat(x, indices)
        names.append('`numpy.{}`'.format(name))
    except:
        pass