REF: collect ops dispatch functions in one place, try to de-duplicate SparseDataFrame methods
Hello @jbrockmendel! Thanks for submitting the PR.

 - There are no PEP8 issues in the file [`pandas/core/frame.py`](https://github.com/jbrockmendel/pandas/blob/5f9d11127678466b8e9fbaf3f8ea191539535e39/pandas/core/frame.py) !

 - There are no PEP8 issues in the file [`pandas/core/ops.py`](https://github.com/jbrockmendel/pandas/blob/5f9d11127678466b8e9fbaf3f8ea191539535e39/pandas/core/ops.py) !

 - There are no PEP8 issues in the file [`pandas/core/sparse/frame.py`](https://github.com/jbrockmendel/pandas/blob/5f9d11127678466b8e9fbaf3f8ea191539535e39/pandas/core/sparse/frame.py) !

 - There are no PEP8 issues in the file [`pandas/tests/arithmetic/test_numeric.py`](https://github.com/jbrockmendel/pandas/blob/5f9d11127678466b8e9fbaf3f8ea191539535e39/pandas/tests/arithmetic/test_numeric.py) !

 # [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/23060?src=pr&el=h1) Report
> Merging [#23060](https://codecov.io/gh/pandas-dev/pandas/pull/23060?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/62a15fa4071d0711b2b97771b981d527c1c4af10?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `95.65%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/23060/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/23060?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master   #23060   +/-   ##
=======================================
  Coverage   92.16%   92.16%           
=======================================
  Files         166      166           
  Lines       51224    51224           
=======================================
  Hits        47212    47212           
  Misses       4012     4012
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.6% <95.65%> (ø)` | :arrow_up: |
| #single | `42.23% <26.08%> (ø)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/23060?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/sparse/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/23060/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc3BhcnNlL2ZyYW1lLnB5) | `94.86% <92.3%> (ø)` | :arrow_up: |
| [pandas/core/ops.py](https://codecov.io/gh/pandas-dev/pandas/pull/23060/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvb3BzLnB5) | `94.24% <97.67%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/23060?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/23060?src=pr&el=footer). Last update [62a15fa...c431373](https://codecov.io/gh/pandas-dev/pandas/pull/23060?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
 Woops, accidentally pushed some unrelated commits collecting arithmetic tests. If it will help, I can separate out the unrelated test parts of this.  There is a bunch of test cleanup to do, and already a healthy number of test-touching PRs in play. > can this be amendednow that that Sparse EA is here? (followup ok too)

@TomAugspurger any idea about this?  I have no clue also happy to merge this and followup later on sparse refactorings (prob better). Ping can you rebase. the isort is playing havoc :> thanks @jbrockmendel nice as always!