Skip to content

BUG: support fused types in roll_min/max #12373 #12481

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 82 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
f27beba
Bugfix for GH12373:
joshuastorck Feb 27, 2016
fcfc200
Bugfix for GH12373:
joshuastorck Feb 27, 2016
1648f8f
Post-rebase move of test_rolling_min_max_numeric_types unit test from…
joshuastorck Feb 27, 2016
ce0d440
Merge branch 'GH12373' of github.com:joshuastorck/pandas into GH12373
joshuastorck Feb 27, 2016
2396314
pyflakes fixup
joshuastorck Feb 27, 2016
bcc987c
BUG: describe() outputs bool similarly to categorical data
Feb 26, 2016
91967c8
ENH: add missing methods to .dt for Period, resolves #8848
andrew-rosenfeld-ts Feb 27, 2016
2e4da9b
ERR: Better error reporting with .transform and an invalid output
Feb 27, 2016
2d2f173
BUG: Simple operation unexpectedly changes dtype.
Feb 26, 2016
4efb5e9
TST/DOC: some test cleanups
jreback Feb 27, 2016
ef6de76
PEP fixes
jreback Feb 27, 2016
cb43b2f
COMPAT: older numpies compat on dtype upcasting, xref #10503
jreback Feb 27, 2016
41b1d25
typo
Feb 28, 2016
bc6ab05
DOC: fixed references to DataFrameGroupBy methods in comparison_with_…
mortada Mar 1, 2016
f263ef9
* Removing struct pairs from algos as it's no longer being
joshuastorck Mar 1, 2016
91b15ab
pyflakes fixup
joshuastorck Mar 1, 2016
65e7ca6
Adding documentation
joshuastorck Mar 1, 2016
170fb27
Fixing sphinx markup in documentation
joshuastorck Mar 1, 2016
1343011
DOC: extract ValueError message
tdhock Feb 29, 2016
3ab35b4
CLN: cleanup strings._wrap_result
sinhrks Mar 2, 2016
eba7803
CLN: Removed pandas.util.testing.choice
paul-reiners Mar 2, 2016
84781b4
COMPAT: blacklist numexpr=2.4.4
jreback Mar 3, 2016
9b9c7a7
BUG: Make Styler ignore None index names to match to_html behaviour
TomAugspurger Mar 3, 2016
9313089
BUG: Make dict iterators real iterators, provide "next()" in Python 2
toobaz Mar 3, 2016
c69037c
BUG: Fixed grow_buffer to grow when capacity is reached
gfyoung Mar 3, 2016
c387fd8
TST: Rework style test skip
TomAugspurger Mar 4, 2016
3928102
CI: pin libgfortran=1.0
jreback Mar 4, 2016
60b307f
ENH: optional ':' separator in ISO8601 strings
thejohnfreeman Mar 5, 2016
486fcfa
Fix typo
yuvallanger Mar 5, 2016
55f21ca
Revert "ENH: optional ':' separator in ISO8601 strings"
jreback Mar 5, 2016
3d70be7
BUG: rolling functions raise ValueError on float32 data
BranYang Feb 18, 2016
a0aaad9
TST: more comprehensive dtype testing for rolling
jreback Mar 5, 2016
547c784
ENH: Allow exponentially weighted functions to specify alpha directly
Mar 6, 2016
a174898
BUG: Allow assignment by indexing with duplicate column names
gfyoung Mar 6, 2016
820e110
ENH: Optional ':' HHMMSS separator in ISO8601 strings
thejohnfreeman Feb 27, 2016
a58ad4f
BLD: Install texlive packages in Travis CI
Mar 6, 2016
0b1e1c9
TST: Add more period tests
sinhrks Mar 7, 2016
13b7a40
Added pandas logo and separator
philipgura Mar 7, 2016
23fb736
DOC: fix doc build warnings
jreback Mar 8, 2016
07c84d5
CI: fix appveyor to use fixed versioning
jreback Mar 7, 2016
5f7e290
API: allow scalar setting/getting via float indexer on integer indexes
jreback Mar 8, 2016
14cf67f
BUG: resample fixes
jreback Mar 8, 2016
0d082c6
TST: nicer output from pd.test()
jreback Mar 9, 2016
b168377
CI: add osx to travis, xref #8630
jreback Mar 8, 2016
8bc66eb
DOC: fix doc-build warnings & cleanup
jreback Mar 9, 2016
e5ed87b
RLS: v0.18.0rc2
jreback Mar 9, 2016
b43617d
removed Panel.to_json from docs
Mar 10, 2016
19e40a0
CI: remove leading v from built versions
jreback Mar 10, 2016
fcab956
DOC: clean up some doc-build warnings
jreback Mar 9, 2016
f258844
CI/BLD: suppress cython warnings
jreback Mar 10, 2016
e9fde88
BLD: suppress useless warnings
jreback Mar 11, 2016
71b7237
Resolve ImportError in read_gbq which appears with oauthclient >= 2.0
tonypartheniou Mar 10, 2016
d14dc1b
BLD: allow different options for compiler warnings on windows
jreback Mar 11, 2016
7c7f987
Using cython ndarray creation so that the numpy array owns its data
joshuastorck Mar 11, 2016
c22f0b0
Bugfix for GH12373:
joshuastorck Feb 27, 2016
3cd5fce
Post-rebase move of test_rolling_min_max_numeric_types unit test from…
joshuastorck Feb 27, 2016
3689db4
pyflakes fixup
joshuastorck Feb 27, 2016
4e16006
* Removing struct pairs from algos as it's no longer being
joshuastorck Mar 1, 2016
068200f
pyflakes fixup
joshuastorck Mar 1, 2016
83e4df2
Adding documentation
joshuastorck Mar 1, 2016
e06f79c
Fixing sphinx markup in documentation
joshuastorck Mar 1, 2016
a08982c
Using cython ndarray creation so that the numpy array owns its data
joshuastorck Mar 11, 2016
ab3a727
Merge from fork
joshuastorck Mar 11, 2016
bb0044b
Bugfix for GH12373:
joshuastorck Feb 27, 2016
4721216
Post-rebase move of test_rolling_min_max_numeric_types unit test from…
joshuastorck Feb 27, 2016
e3f3faa
pyflakes fixup
joshuastorck Feb 27, 2016
5407403
* Removing struct pairs from algos as it's no longer being
joshuastorck Mar 1, 2016
1fb511d
pyflakes fixup
joshuastorck Mar 1, 2016
a5f5c2c
Adding documentation
joshuastorck Mar 1, 2016
da0a186
Fixing sphinx markup in documentation
joshuastorck Mar 1, 2016
972d84e
Using cython ndarray creation so that the numpy array owns its data
joshuastorck Mar 11, 2016
70f353d
Adding documentation
joshuastorck Mar 1, 2016
1e588a7
Fixing bad merge from rebase
joshuastorck Mar 11, 2016
d5e1701
Add as_float to all of the cases for the _Window._prep_values functio…
joshuastorck Mar 11, 2016
2cd6079
Merge with origin
joshuastorck Mar 11, 2016
c400eef
Adding whitespace
joshuastorck Mar 11, 2016
000652c
Removing whitespace
joshuastorck Mar 11, 2016
a6cfc78
DOC: whatsnew and doc changes
jreback Mar 11, 2016
298cbfa
DOC: add release note thanks
jreback Mar 11, 2016
8294bf2
DOC: Fixes LaTeX build error
TomAugspurger Mar 11, 2016
9c85b9d
Bugfix for GH12373:
joshuastorck Feb 27, 2016
300eea5
Merge branch 'GH12373' of github.com:joshuastorck/pandas into GH12373
joshuastorck Mar 11, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 69 additions & 115 deletions pandas/algos.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1633,21 +1633,34 @@ from libc cimport stdlib

@cython.boundscheck(False)
@cython.wraparound(False)
def roll_max(ndarray[float64_t] a, int window, int minp):
"Moving max of 1d array of dtype=float64 along axis=0 ignoring NaNs."
cdef np.float64_t ai, aold
def roll_max(ndarray[numeric] a, int window, int minp):
"Moving max of 1d array of any numeric type along axis=0 ignoring NaNs."
return _roll_min_max(a, window, minp, 1)

@cython.boundscheck(False)
@cython.wraparound(False)
def roll_min(ndarray[numeric] a, int window, int minp):
"Moving min of 1d array of any numeric type along axis=0 ignoring NaNs."
return _roll_min_max(a, window, minp, 0)

@cython.boundscheck(False)
@cython.wraparound(False)
def _roll_min_max(ndarray[numeric] a, int window, int minp, bint is_max):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be cdef

"Moving min/max of 1d array of any numeric type along axis=0 ignoring NaNs."
cdef numeric ai, aold
cdef Py_ssize_t count
cdef pairs* ring
cdef pairs* minpair
cdef pairs* end
cdef pairs* last
cdef Py_ssize_t* death
cdef numeric* ring
cdef numeric* minpair
cdef numeric* end
cdef numeric* last
cdef Py_ssize_t i0
cdef np.npy_intp *dim
dim = PyArray_DIMS(a)
cdef Py_ssize_t n0 = dim[0]
cdef np.npy_intp *dims = [n0]
cdef np.ndarray[np.float64_t, ndim=1] y = PyArray_EMPTY(1, dims,
NPY_float64, 0)
cdef numeric* y
cdef bint should_replace

if window < 1:
raise ValueError('Invalid window size %d'
Expand All @@ -1659,57 +1672,79 @@ def roll_max(ndarray[float64_t] a, int window, int minp):

minp = _check_minp(window, minp, n0)
with nogil:
ring = <pairs*>stdlib.malloc(window * sizeof(pairs))
ring = <numeric*>stdlib.malloc(window * sizeof(numeric))
death = <Py_ssize_t*>stdlib.malloc(window * sizeof(Py_ssize_t))
y = <numeric*>stdlib.malloc(n0 * sizeof(numeric))
end = ring + window
last = ring

minpair = ring
minvalue = ring
ai = a[0]
if ai == ai:
minpair.value = ai
if numeric in cython.floating:
if ai == ai:
minvalue[0] = ai
elif is_max:
minvalue[0] = MINfloat64
else:
minvalue[0] = MAXfloat64
else:
minpair.value = MINfloat64
minpair.death = window
minvalue[0] = ai
death[0] = window

count = 0
for i0 in range(n0):
ai = a[i0]
if ai == ai:
count += 1
if numeric in cython.floating:
if ai == ai:
count += 1
elif is_max:
ai = MINfloat64
else:
ai = MAXfloat64
else:
ai = MINfloat64
count += 1
if i0 >= window:
aold = a[i0 - window]
if aold == aold:
count -= 1
if minpair.death == i0:
minpair += 1
if minpair >= end:
minpair = ring
if ai >= minpair.value:
minpair.value = ai
minpair.death = i0 + window
last = minpair
if death[minvalue-ring] == i0:
minvalue += 1
if minvalue >= end:
minvalue = ring
should_replace = ai >= minvalue[0] if is_max else ai <= minvalue[0]
if should_replace:
minvalue[0] = ai
death[minvalue-ring] = i0 + window
last = minvalue
else:
while last.value <= ai:
should_replace = last[0] <= ai if is_max else last[0] >= ai
while should_replace:
if last == ring:
last = end
last -= 1
should_replace = last[0] <= ai if is_max else last[0] >= ai
last += 1
if last == end:
last = ring
last.value = ai
last.death = i0 + window
if count >= minp:
y[i0] = minpair.value
last[0] = ai
death[last - ring] = i0 + window
if numeric in cython.floating:
if count >= minp:
y[i0] = minvalue[0]
else:
y[i0] = NaN
else:
y[i0] = NaN
y[i0] = minvalue[0]

for i0 in range(minp - 1):
y[i0] = NaN
if numeric in cython.floating:
y[i0] = NaN
else:
y[i0] = 0

stdlib.free(ring)
return y
stdlib.free(death)
return PyArray_SimpleNewFromData(1, dims, PyArray_TYPE(a), y)


cdef double_t _get_max(object skiplist, int nobs, int minp):
Expand All @@ -1718,87 +1753,6 @@ cdef double_t _get_max(object skiplist, int nobs, int minp):
else:
return NaN


@cython.boundscheck(False)
@cython.wraparound(False)
def roll_min(np.ndarray[np.float64_t, ndim=1] a, int window, int minp):
"Moving min of 1d array of dtype=float64 along axis=0 ignoring NaNs."
cdef np.float64_t ai, aold
cdef Py_ssize_t count
cdef pairs* ring
cdef pairs* minpair
cdef pairs* end
cdef pairs* last
cdef Py_ssize_t i0
cdef np.npy_intp *dim
dim = PyArray_DIMS(a)
cdef Py_ssize_t n0 = dim[0]
cdef np.npy_intp *dims = [n0]
cdef np.ndarray[np.float64_t, ndim=1] y = PyArray_EMPTY(1, dims,
NPY_float64, 0)

if window < 1:
raise ValueError('Invalid window size %d'
% (window))

if minp > window:
raise ValueError('Invalid min_periods size %d greater than window %d'
% (minp, window))

minp = _check_minp(window, minp, n0)
with nogil:
ring = <pairs*>stdlib.malloc(window * sizeof(pairs))
end = ring + window
last = ring

minpair = ring
ai = a[0]
if ai == ai:
minpair.value = ai
else:
minpair.value = MAXfloat64
minpair.death = window

count = 0
for i0 in range(n0):
ai = a[i0]
if ai == ai:
count += 1
else:
ai = MAXfloat64
if i0 >= window:
aold = a[i0 - window]
if aold == aold:
count -= 1
if minpair.death == i0:
minpair += 1
if minpair >= end:
minpair = ring
if ai <= minpair.value:
minpair.value = ai
minpair.death = i0 + window
last = minpair
else:
while last.value >= ai:
if last == ring:
last = end
last -= 1
last += 1
if last == end:
last = ring
last.value = ai
last.death = i0 + window
if count >= minp:
y[i0] = minpair.value
else:
y[i0] = NaN

for i0 in range(minp - 1):
y[i0] = NaN

stdlib.free(ring)
return y

cdef double_t _get_min(object skiplist, int nobs, int minp):
if nobs >= minp:
return <IndexableSkiplist> skiplist.get(0)
Expand Down
11 changes: 11 additions & 0 deletions pandas/tests/test_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -2432,3 +2432,14 @@ def test_rolling_median_memory_error(self):
n = 20000
Series(np.random.randn(n)).rolling(window=2, center=False).median()
Series(np.random.randn(n)).rolling(window=2, center=False).median()

def test_rolling_min_max_numeric_types(self):
# GH12373
types_test = [np.dtype("f{}".format(width)) for width in [4, 8]]
types_test.extend([np.dtype("{}{}".format(sign, width))
for width in [1, 2, 4, 8] for sign in "ui"])
for data_type in types_test:
# Just testing that these don't throw exceptions. Other tests will
# cover quantitative correctness
DataFrame(np.arange(20, dtype=data_type)).rolling(window=5).max()
DataFrame(np.arange(20, dtype=data_type)).rolling(window=5).min()