[WIP] ENH: Groupby mode
- [x] closes #19254 
- [ ] tests added / passed
- [x] Ensure all linting tests pass, see [here](https://pandas.pydata.org/pandas-docs/dev/development/contributing.html#code-standards) for how to run them
- [ ] whatsnew entry

Proof of concept for #19254 

Is relatively fast compared to @rhshadrach method
```
In [4]: %timeit df.groupby("a").mode()
2.52 ms ± 415 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [5]: %timeit df.groupby("a").mode()
1.99 ms ± 60.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [6]: %timeit gb_mode(df, ['a'], 'b')
3.9 ms ± 310 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [7]: %timeit gb_mode(df, ['a'], 'b')
3.8 ms ± 270 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [8]: %timeit gb_mode(df, ['a'], 'b')
3.89 ms ± 433 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```

API for what to do when multimodal needs discussion though. 
Thanks @lithomas1! Can you include the frame used for the time test? If the values don't have high cardinality (> 500 distinct values?), can you also test with one that does? My expectation is that the cython implementation performs much better the larger the distinct values are. Dont have time for this.