ENH: Add argument "multiprocessing" to DataFrame.apply() method (any axis)
#### Is your feature request related to a problem?

When a function is passed to DataFrame.apply (with any axis) unfortunately, this doesn't take advantage of the multiprocessing module, making it inefficient for large datasets, especially when more cores are available to work.

Other modules like modin or dask, already implement this, but I think that pandas should implement by itself, if called for.

#### Describe the solution you'd like

It should be able to work with the multiprocessing module out of the box, as an initial enhancement, and then in the future support other possible backends like joblib.

An example of application would be:

`df.apply(lambda x: x['A'] * x['B'], axis=1, multiprocessing=True)`

#### API breaking implications

This should not change established behavior, considering that the default value for the "multiprocessing" argument should be "None" by default.

The only concern would be to return the DataFrame without changing indices, and the result be the same as without multiprocessing.

#### Describe alternatives you've considered

I have also considered extra backend options for future enhancements of this implementation, like joblib, ray, dask.

#### Additional context

NOTE: I have already a proof-of-concept for the solution, so I can work a bit further on it.
