CLN/TYP: aggregation methods in core.base
- [ ] closes #xxxx
- [ ] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry

This is in order to move _aggregate and _aggregate_multiple_funcs into core.aggregation - I think that's desirable. Type-hinting is slightly more strong there (checks untyped defs), and would involve renaming `self` to `obj`. Thus the renaming of `obj` to `selected_obj` here.
1 mypy complaint Thanks @jbrockmendel. The offending line is:

    name = self.name if (self.ndim == 1) else None

A natural replacement would be to do:

```
if isinstance(self, ABCSeries):
    name = self.name
else:
    name = None
```

but in general I think we prefer checking `ndim == 1` rather than `isinstance` for performance when the object is known to be a Series/DataFrame. So the other options I see here are to use cast (is `self = cast(self, ...)` okay?) or just silence mypy with # type: ignore (along with the specific code).

Any advice here @simonjayhawkins, @jbrockmendel, @jreback? i tend to use the ndim check, but no strong opinion I fixed by using cast; ready for review now. @simonjayhawkins  @simonjayhawkins Thanks for you're input. I've changed the code back to use `if ndim == 1` along with `cast`. I think this is what you meant by "may as well [cast] now" - let me know if I misunderstood. thanks @rhshadrach 