Implementing rolling min/max functions that can retain the original type
State: closed

- [ ] Enhances previous bugfix to #12373 
- [ ] Added test_rolling_min_max_test_types to test_windows
- [ ] passes `git diff upstream/master | flake8 --diff`
- [ ] Added documentation to computation.rst for the new as_float argument and updated whatsnew for v0.18.0
  - Changed the rolling min/max functions in algos.pyx so
    that they use a cython fused type as input instead of a float64
    so that the function can accept arrays of any numeric type
  - Merged the functionality of rolling min/max into a common
    function with branches based on whether or not it's running
    min/max
  - When running rolling min/max for intergral types and there
    are not enough minimum periods, the output values returned
    are zero
  - Added a unit test to test_moments to make sure that rolling
    min/max works for all integral types and float32/64
  - Updated computations and whatsnew doc


Labels:
name: Reshaping
description: Concat, Merge/Join, Stack/Unstack, Explode
name: Dtype Conversions
description: Unexpected or buggy dtype conversions
name: Numeric Operations
description: Arithmetic, Comparison, and Logical operations

Comments:
> When running rolling min/max for intergral types and there are not enough minimum periods, the output values returned are zero

I don't think 0 is sensible, but I'm not sure how else it can be done either without integral nulls.

> Merged the functionality of rolling min/max into a common function with branches based on whether or not it's running min/max

the branching can be decided very soon (your `is_max`), so you don't need to branch in the loop

If you branched earlier, you would effectively be passing around a function pointer. That doesn't give the compiler any opportunity to do something smarter, like a conditional move, which in this case would be pretty easy to generate. 

Ideally, much of this code should be written in native C++ with templates using C++11 lambdas. That would make it possible to eliminate branching completely at compile time.

@joshuastorck  Ah! I see!  

Any additional work needed on this one?

will take a look - can u rebase in master

Just rebased and pushed

also pls `git rebase -i master` then push upstream (with `-f`).

nvm. you are only 1 or 2 commits behind.

I think you need to take out some of the `_ensure_float64` that were implemented in the related PR.

I would expect this to return `float32` no?

```
In [4]: Series([1,2,3,4],dtype='float32').rolling(window=2).max()
Out[4]: 
0    NaN
1    2.0
2    3.0
3    4.0
dtype: float64

```

pretty much everything else is going to be upcast though

That was why I originally had an as_float argument, which was in there for backwards compatibility. Are you saying that you are ok with breaking type compatibility?

@joshuastorck not sure what you mean. We are _now_ breaking type compat by casing to `float64`. if you can preserve the type then by all means do it. You don't need a flag for that it should just work. Of course for integers ATM this won't work, but that's a different issue.

So you want this code in window.py:

```
        # GH #12373 : rolling functions error on float32 data
        # make sure the data is coerced to float64
        if com.is_float_dtype(values.dtype):
            values = com._ensure_float64(values)
        elif com.is_integer_dtype(values.dtype):
            values = com._ensure_float64(values)

```

To change to this?

```
        if com.is_integer_dtype(values.dtype):
            values = com._ensure_float64(values)

```

Also, I only changed the roll_min/max functions. Wouldn't that code change break all of the other rolling functions?

hmm, yes ideally that would be the change. But you are right the rest have not been converted. ok then.

pls squash / ping when green.

ok, I linked the master issue: https://github.com/pydata/pandas/issues/8659

so next up is fixing the remainder of the rolling functions, so we don't need to upcast floats. :)

Rebased and Travis CI is green

@joshuastorck thanks for the fixes!

#8659 (using fused types in the rest of the algos) is waiting for you!

@joshuastorck  going to start going thru your changes for support on [this](https://github.com/jreback/pandas/commit/5985ae7803801264240809faf4a90f02c27836e5)