CLN/ENH: Provide full suite of arithmetic (and flex) methods to all NDFrame objects.
State: closed

Resolves #3765, #4331, #4334, #4051.

This goes on top of @jreback's Series refactoring (#3482). If you want to review, I suggest looking [at the PR on top of jreback/series2](https://github.com/jreback/pandas/pull/6), so you only see the diffs specific to this PR.

This does a few things:
1. Normalizes the arithmetic signature so that all objects have the full-range of special methods, inplace methods and `__r*__` methods. Similarly, most objects get the full-range of flex methods (varies based on the object.
2. Refactors all arithmetic methods to `core/ops` and adds methods to add both special (e.g., `__add__`) and flex (e.g. `add()`) to PandasObjects.
3. Slight refactoring of the arithmetic methods themselves to abstract the common `na_op` idiom into a single function.
4. Uses `numexpr` throughout for most operations (except for the sparse objects)
5. Makes it easier to create new `PandasObjects` that support all arithmetic methods - just need to define 2-5 functions.
6. Establishes a standard type signature for arithmetic methods [documented in core/ops], specifically:
-  arithmetic method: `f(op, name, str_rep, default_axis=None, fill_zeros=None, **eval_kwargs)`
-  comp/bool method: `f(op, name, str_rep)`

This is a straight continuation of #4051, but since it's different enough (especially with moving the operations to core/ops and no longer using them as classmethods), I'm doing it in a separate PR.

I'm open to changing the naming of the arithmetic functions in core/ops. I named them as they are to make it easier to move them into `core/ops`

Sidenote: I don't know whether numexpr plays well with sparse objects (or if that's even an issue). It's trivial to disable numexpr on Sparse* objects, just need to know what you want to do.


Labels:

Comments:
second side note - adding a `truediv` method to Series and DataFrame was the major reason that I started contributing to pandas. 2 months or so later, I finally got to a PR.

@jtratner nice! i love those little anecdotes :smile: 

sparse is prob not tested for Numexpr
and won't work I think; disable for now

@jreback okay. I'll make that change.

@jtratner ok.....just rebased, so try your git fu!

@jreback did you change any of the Series arithmetic in your last rebase? Hard to tell b/c of all the file movement :P  I thought you did, but then I rechecked and it didn't look like it.

the timedelta/datetime ops were changed around (in the wrapper); you have it now in core/ops.py, you should be able to use my version with only slight mods I think

@jreback do you have a link to the PR you merged in? Just helpful to have it to look at. Thanks for clarifying tho.

@jreback found the PR. it's all good ... guess I just missed that whole thing. Thanks for the tip!

trying to make it smooth
hopefully can get merged soon

I'm closing this for now because I'm not convinced test suite for time arithmetic is checking rops and I don't want it to be accidentally merged.

@jtratner just merged #3482! so you are up with this!

Awesome, now I just have to make datetime arithmetic play nicely with r*
methods.

lmk...

@jreback what's the difference between 'i8' dtype and np.int64? On my system it looks like they are the same...

same
integer 8 = 8 x 8 = 64 bit

Thanks -  that's really helpful!

@jtratner Also check out `np.typeDict`: it's a `dict` mapping `str` names to `dtype`s. Pretty useful :smile: