From d595aeaaf9400b76bd2b1107d8ac458d36b5d552 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 22 Dec 2019 13:14:58 +0300 Subject: [PATCH 01/10] Overload series.rolling.apply() --- .../series/rolling/series_rolling_apply.py | 44 +++++++ .../hpat_pandas_series_rolling_functions.py | 115 +++++++++++++++++- sdc/tests/test_rolling.py | 53 ++++++++ 3 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 examples/series/rolling/series_rolling_apply.py diff --git a/examples/series/rolling/series_rolling_apply.py b/examples/series/rolling/series_rolling_apply.py new file mode 100644 index 000000000..78ebd7ba2 --- /dev/null +++ b/examples/series/rolling/series_rolling_apply.py @@ -0,0 +1,44 @@ +# ***************************************************************************** +# Copyright (c) 2019, Intel Corporation All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ***************************************************************************** + +import numpy as np +import pandas as pd +from numba import njit + + +@njit +def series_rolling_apply(): + series = pd.Series([4, 3, 5, 2, 6]) # Series of 4, 3, 5, 2, 6 + + def get_median(x): + return np.median(x) + + out_series = series.rolling(3).apply(get_median) + + return out_series # Expect series of NaN, NaN, 4.0, 3.0, 5.0 + + +print(series_rolling_apply()) diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index 6a2639bf7..5a82ec3e7 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -29,13 +29,20 @@ from numba import prange from numba.extending import register_jitable -from numba.types import float64 +from numba.types import float64, Boolean, NoneType, Omitted from sdc.datatypes.common_functions import TypeChecker from sdc.datatypes.hpat_pandas_series_rolling_types import SeriesRollingType from sdc.utils import sdc_overload_method +@register_jitable +def arr_apply(arr, func): + """Apply function for values""" + # Use np.apply_along_axis when it's supported by Numba to apply array with infinite values + return func(arr) + + @register_jitable def arr_nonnan_count(arr): """Count non-NaN values""" @@ -130,6 +137,112 @@ def impl(self): gen_hpat_pandas_series_rolling_impl(arr_min, float64)) +@sdc_overload_method(SeriesRollingType, 'apply') +def hpat_pandas_series_rolling_apply(self, func, raw=None): + """ + Intel Scalable Dataframe Compiler User Guide + ******************************************** + Pandas API: pandas.core.window.Rolling.apply + + Limitations + ----------- + Supported ``raw`` only can be `None` or `True`. + Series elements cannot be max/min float/integer and infinite. + Otherwise SDC and Pandas results are different. + + Examples + -------- + .. literalinclude:: ../../../examples/series/rolling/series_rolling_apply.py + :language: python + :lines: 27- + :caption: Calculate the rolling apply. + :name: ex_series_rolling_apply + + .. code-block:: console + + > python ./series_rolling_apply.py + 0 NaN + 1 NaN + 2 4.0 + 3 3.0 + 4 5.0 + dtype: float64 + + .. seealso:: + :ref:`Series.rolling ` + Calling object with a Series. + :ref:`DataFrame.rolling ` + Calling object with a DataFrame. + :ref:`Series.apply ` + Similar method for Series. + :ref:`DataFrame.apply ` + Similar method for DataFrame. + + Intel Scalable Dataframe Compiler Developer Guide + ************************************************* + + Pandas Series method :meth:`pandas.Series.rolling.apply()` implementation. + + .. only:: developer + + Test: python -m sdc.runtests -k sdc.tests.test_rolling.TestRolling.test_series_rolling_apply + + Parameters + ---------- + self: :class:`pandas.Series.rolling` + input arg + func: :obj:`function` + A single value producer + raw: :obj:`bool` + False : passes each row or column as a Series to the function. + True or None : the passed function will receive ndarray objects instead. + *args: + Arguments to be passed into func. + *unsupported* + + Returns + ------- + :obj:`pandas.Series` + returns :obj:`pandas.Series` object + """ + + ty_checker = TypeChecker('Method rolling.apply().') + ty_checker.check(self, SeriesRollingType) + + raw_accepted = (Omitted, NoneType, Boolean) + if not isinstance(raw, raw_accepted) and raw is not None: + ty_checker.raise_exc(raw, 'bool', 'raw') + + def hpat_pandas_rolling_series_apply_impl(self, func, raw=None): + win = self._window + minp = self._min_periods + + input_series = self._data + input_arr = input_series._data + length = len(input_arr) + output_arr = numpy.empty(length, dtype=float64) + + def culc_apply(arr, func, minp): + finite_arr = arr[numpy.isfinite(arr)] + if len(finite_arr) < minp: + return numpy.nan + else: + return arr_apply(finite_arr, func) + + boundary = min(win, length) + for i in prange(boundary): + arr_range = input_arr[:i + 1] + output_arr[i] = culc_apply(arr_range, func, minp) + + for i in prange(min(win, length), length): + arr_range = input_arr[i + 1 - win:i + 1] + output_arr[i] = culc_apply(arr_range, func, minp) + + return pandas.Series(output_arr, input_series._index, name=input_series._name) + + return hpat_pandas_rolling_series_apply_impl + + @sdc_overload_method(SeriesRollingType, 'count') def hpat_pandas_series_rolling_count(self): """ diff --git a/sdc/tests/test_rolling.py b/sdc/tests/test_rolling.py index f8cba375f..3f10194b4 100644 --- a/sdc/tests/test_rolling.py +++ b/sdc/tests/test_rolling.py @@ -492,6 +492,59 @@ def test_impl(series, window, min_periods, center, msg = msg_tmpl.format('closed', 'int64', 'str') self.assertIn(msg, str(raises.exception)) + @skip_sdc_jit('Series.rolling.apply() unsupported Series index') + def test_series_rolling_apply_median(self): + def test_impl(series, window, min_periods): + def func(x): + if len(x) == 0: + return np.nan + return np.median(x) + return series.rolling(window, min_periods).apply(func) + + hpat_func = self.jit(test_impl) + + data = [1., -1., 0., 0.1, -0.1] + index = list(range(len(data)))[::-1] + series = pd.Series(data, index, name='A') + for window in range(0, len(series) + 3, 2): + for min_periods in range(0, window + 1, 2): + with self.subTest(window=window, min_periods=min_periods): + jit_result = hpat_func(series, window, min_periods) + ref_result = test_impl(series, window, min_periods) + pd.testing.assert_series_equal(jit_result, ref_result) + + @skip_sdc_jit('Series.rolling.apply() unsupported Series index') + @unittest.expectedFailure + def test_series_rolling_apply_issue_np_apply_along_axis_unsupported(self): + def test_impl(series): + def func(x): + if len(x) == 0: + return np.nan + return np.median(x) + return series.rolling(6, 4).apply(func) + + hpat_func = self.jit(test_impl) + + series = pd.Series([1., -1., np.nan, 0.1, -0.1]) + pd.testing.assert_series_equal(hpat_func(series), test_impl(series)) + + @skip_sdc_jit('Series.rolling.apply() unsupported exceptions') + def test_series_rolling_apply_unsupported_types(self): + def test_impl(raw): + def func(x): + if len(x) == 0: + return np.nan + return np.median(x) + series = pd.Series([1., -1., 0., 0.1, -0.1]) + return series.rolling(3).apply(func, raw=raw) + + hpat_func = self.jit(test_impl) + + with self.assertRaises(TypingError) as raises: + hpat_func(1) + msg = 'Method rolling.apply(). The object raw\n given: int64\n expected: bool' + self.assertIn(msg, str(raises.exception)) + @skip_sdc_jit('Series.rolling.count() unsupported Series index') def test_series_rolling_count(self): def test_impl(series, window, min_periods): From 349e3bbff0be788cb3f263f8de6fa92b2aa26f66 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 22 Dec 2019 19:26:28 +0300 Subject: [PATCH 02/10] Fix issue with infinite values for rolling.apply() --- .../hpat_pandas_series_rolling_functions.py | 3 +- sdc/tests/test_rolling.py | 31 ++++++------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index 5a82ec3e7..091250210 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -223,7 +223,8 @@ def hpat_pandas_rolling_series_apply_impl(self, func, raw=None): output_arr = numpy.empty(length, dtype=float64) def culc_apply(arr, func, minp): - finite_arr = arr[numpy.isfinite(arr)] + finite_arr = arr.copy() + finite_arr[numpy.isinf(arr)] = numpy.nan if len(finite_arr) < minp: return numpy.nan else: diff --git a/sdc/tests/test_rolling.py b/sdc/tests/test_rolling.py index 3f10194b4..8a8ccfbc3 100644 --- a/sdc/tests/test_rolling.py +++ b/sdc/tests/test_rolling.py @@ -496,37 +496,24 @@ def test_impl(series, window, min_periods, center, def test_series_rolling_apply_median(self): def test_impl(series, window, min_periods): def func(x): + print('DEBUG: x:', x) if len(x) == 0: return np.nan + print('DEBUG: np.median(x):', np.median(x)) return np.median(x) return series.rolling(window, min_periods).apply(func) hpat_func = self.jit(test_impl) - data = [1., -1., 0., 0.1, -0.1] + data = [0.1, np.inf, np.inf, 1., -1., 0., np.nan, np.nan, np.NINF, -0.1] index = list(range(len(data)))[::-1] series = pd.Series(data, index, name='A') - for window in range(0, len(series) + 3, 2): - for min_periods in range(0, window + 1, 2): - with self.subTest(window=window, min_periods=min_periods): - jit_result = hpat_func(series, window, min_periods) - ref_result = test_impl(series, window, min_periods) - pd.testing.assert_series_equal(jit_result, ref_result) - - @skip_sdc_jit('Series.rolling.apply() unsupported Series index') - @unittest.expectedFailure - def test_series_rolling_apply_issue_np_apply_along_axis_unsupported(self): - def test_impl(series): - def func(x): - if len(x) == 0: - return np.nan - return np.median(x) - return series.rolling(6, 4).apply(func) - - hpat_func = self.jit(test_impl) - - series = pd.Series([1., -1., np.nan, 0.1, -0.1]) - pd.testing.assert_series_equal(hpat_func(series), test_impl(series)) + for window in range(0, len(series) + 1, 2): + min_periods = window + with self.subTest(window=window, min_periods=min_periods): + jit_result = hpat_func(series, window, min_periods) + ref_result = test_impl(series, window, min_periods) + pd.testing.assert_series_equal(jit_result, ref_result) @skip_sdc_jit('Series.rolling.apply() unsupported exceptions') def test_series_rolling_apply_unsupported_types(self): From bd9dd650e1d32cd9df91af387e8d70180347305a Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 22 Dec 2019 20:02:18 +0300 Subject: [PATCH 03/10] Replace applying median with mean for testing --- sdc/tests/test_rolling.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/sdc/tests/test_rolling.py b/sdc/tests/test_rolling.py index 8a8ccfbc3..b4e759b09 100644 --- a/sdc/tests/test_rolling.py +++ b/sdc/tests/test_rolling.py @@ -493,27 +493,31 @@ def test_impl(series, window, min_periods, center, self.assertIn(msg, str(raises.exception)) @skip_sdc_jit('Series.rolling.apply() unsupported Series index') - def test_series_rolling_apply_median(self): + def test_series_rolling_apply_mean(self): def test_impl(series, window, min_periods): def func(x): - print('DEBUG: x:', x) if len(x) == 0: return np.nan - print('DEBUG: np.median(x):', np.median(x)) - return np.median(x) + return x.mean() return series.rolling(window, min_periods).apply(func) hpat_func = self.jit(test_impl) - data = [0.1, np.inf, np.inf, 1., -1., 0., np.nan, np.nan, np.NINF, -0.1] - index = list(range(len(data)))[::-1] - series = pd.Series(data, index, name='A') - for window in range(0, len(series) + 1, 2): - min_periods = window - with self.subTest(window=window, min_periods=min_periods): - jit_result = hpat_func(series, window, min_periods) - ref_result = test_impl(series, window, min_periods) - pd.testing.assert_series_equal(jit_result, ref_result) + all_data = [ + list(range(10)), [1., -1., 0., 0.1, -0.1], + [1., np.inf, np.inf, -1., 0., np.inf, np.NINF, np.NINF], + [np.nan, np.inf, np.inf, np.nan, np.nan, np.nan, np.NINF, np.NZERO] + ] + indices = [list(range(len(data)))[::-1] for data in all_data] + for data, index in zip(all_data, indices): + series = pd.Series(data, index, name='A') + for window in range(len(series) + 1): + min_periods = window + with self.subTest(series=series, window=window, + min_periods=min_periods): + jit_result = hpat_func(series, window, min_periods) + ref_result = test_impl(series, window, min_periods) + pd.testing.assert_series_equal(jit_result, ref_result) @skip_sdc_jit('Series.rolling.apply() unsupported exceptions') def test_series_rolling_apply_unsupported_types(self): From 0d11e2dbae036327f1732fca5a6c4790e24a66c9 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 22 Dec 2019 20:10:19 +0300 Subject: [PATCH 04/10] Use docstring template for series.rolling.apply() --- .../hpat_pandas_series_rolling_functions.py | 88 +++++-------------- 1 file changed, 22 insertions(+), 66 deletions(-) diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index 98336ab12..caf103d32 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -206,72 +206,6 @@ def impl(self): @sdc_overload_method(SeriesRollingType, 'apply') def hpat_pandas_series_rolling_apply(self, func, raw=None): - """ - Intel Scalable Dataframe Compiler User Guide - ******************************************** - Pandas API: pandas.core.window.Rolling.apply - - Limitations - ----------- - Supported ``raw`` only can be `None` or `True`. - Series elements cannot be max/min float/integer and infinite. - Otherwise SDC and Pandas results are different. - - Examples - -------- - .. literalinclude:: ../../../examples/series/rolling/series_rolling_apply.py - :language: python - :lines: 27- - :caption: Calculate the rolling apply. - :name: ex_series_rolling_apply - - .. code-block:: console - - > python ./series_rolling_apply.py - 0 NaN - 1 NaN - 2 4.0 - 3 3.0 - 4 5.0 - dtype: float64 - - .. seealso:: - :ref:`Series.rolling ` - Calling object with a Series. - :ref:`DataFrame.rolling ` - Calling object with a DataFrame. - :ref:`Series.apply ` - Similar method for Series. - :ref:`DataFrame.apply ` - Similar method for DataFrame. - - Intel Scalable Dataframe Compiler Developer Guide - ************************************************* - - Pandas Series method :meth:`pandas.Series.rolling.apply()` implementation. - - .. only:: developer - - Test: python -m sdc.runtests -k sdc.tests.test_rolling.TestRolling.test_series_rolling_apply - - Parameters - ---------- - self: :class:`pandas.Series.rolling` - input arg - func: :obj:`function` - A single value producer - raw: :obj:`bool` - False : passes each row or column as a Series to the function. - True or None : the passed function will receive ndarray objects instead. - *args: - Arguments to be passed into func. - *unsupported* - - Returns - ------- - :obj:`pandas.Series` - returns :obj:`pandas.Series` object - """ ty_checker = TypeChecker('Method rolling.apply().') ty_checker.check(self, SeriesRollingType) @@ -568,6 +502,28 @@ def hpat_pandas_series_rolling_sum(self): return hpat_pandas_rolling_series_sum_impl +hpat_pandas_series_rolling_apply.__doc__ = hpat_pandas_series_rolling_docstring_tmpl.format(**{ + 'method_name': 'apply', + 'example_caption': 'Calculate the rolling apply.', + 'example_result': + """ + 0 NaN + 1 NaN + 2 4.0 + 3 3.0 + 4 5.0 + dtype: float64 + """, + 'limitations_block': + """ + Limitations + ----------- + Supported ``raw`` only can be `None` or `True`. + Series elements cannot be max/min float/integer. Otherwise SDC and Pandas results are different. + """ +}) + + hpat_pandas_series_rolling_mean.__doc__ = hpat_pandas_series_rolling_docstring_tmpl.format(**{ 'method_name': 'mean', 'example_caption': 'Calculate the rolling mean of the values.', From c6b8e6bc2c2e58e38b060fbb8bfcf03e37446038 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 22 Dec 2019 20:13:12 +0300 Subject: [PATCH 05/10] Remove excess comment for series.rolling.apply() --- sdc/datatypes/hpat_pandas_series_rolling_functions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index caf103d32..bda88e2cc 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -87,7 +87,6 @@ @register_jitable def arr_apply(arr, func): """Apply function for values""" - # Use np.apply_along_axis when it's supported by Numba to apply array with infinite values return func(arr) From a2191a9579383b48b273f97e1d18bd4adcc27c4d Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 22 Dec 2019 20:15:42 +0300 Subject: [PATCH 06/10] Expand test for series.rolling.apply() --- sdc/tests/test_rolling.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sdc/tests/test_rolling.py b/sdc/tests/test_rolling.py index 88a107048..1beadfb51 100644 --- a/sdc/tests/test_rolling.py +++ b/sdc/tests/test_rolling.py @@ -511,13 +511,13 @@ def func(x): indices = [list(range(len(data)))[::-1] for data in all_data] for data, index in zip(all_data, indices): series = pd.Series(data, index, name='A') - for window in range(len(series) + 1): - min_periods = window - with self.subTest(series=series, window=window, - min_periods=min_periods): - jit_result = hpat_func(series, window, min_periods) - ref_result = test_impl(series, window, min_periods) - pd.testing.assert_series_equal(jit_result, ref_result) + for window in range(0, len(series) + 3, 2): + for min_periods in range(0, window + 1, 2): + with self.subTest(series=series, window=window, + min_periods=min_periods): + jit_result = hpat_func(series, window, min_periods) + ref_result = test_impl(series, window, min_periods) + pd.testing.assert_series_equal(jit_result, ref_result) @skip_sdc_jit('Series.rolling.apply() unsupported exceptions') def test_series_rolling_apply_unsupported_types(self): From 32ecd2fa19da0c12fed99c8ef992633b17d3cd04 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 23 Dec 2019 16:21:56 +0300 Subject: [PATCH 07/10] Minor fix for series.rolling.apply() --- sdc/datatypes/hpat_pandas_series_rolling_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index d7c992c13..1ae5f99cb 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -271,7 +271,7 @@ def culc_apply(arr, func, minp): arr_range = input_arr[:i + 1] output_arr[i] = culc_apply(arr_range, func, minp) - for i in prange(min(win, length), length): + for i in prange(boundary, length): arr_range = input_arr[i + 1 - win:i + 1] output_arr[i] = culc_apply(arr_range, func, minp) From bef211fa71437fbddfa46389296c9a8d4de5d9e5 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 31 Dec 2019 12:51:20 +0300 Subject: [PATCH 08/10] Fix docstring for series.rolling.apply() --- sdc/datatypes/hpat_pandas_series_rolling_functions.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index 2d1cf4553..8e0d96d47 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -790,15 +790,6 @@ def culc_var(arr, ddof, minp): hpat_pandas_series_rolling_apply.__doc__ = hpat_pandas_series_rolling_docstring_tmpl.format(**{ 'method_name': 'apply', 'example_caption': 'Calculate the rolling apply.', - 'example_result': - """ - 0 NaN - 1 NaN - 2 4.0 - 3 3.0 - 4 5.0 - dtype: float64 - """, 'limitations_block': """ Limitations From fba61f47b5406c038052a3f41295b357623f2b09 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 5 Jan 2020 00:23:21 +0300 Subject: [PATCH 09/10] Add "args/kwargs unsuppoted" to docstring --- sdc/datatypes/hpat_pandas_series_rolling_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index 8e0d96d47..236b81a05 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -794,7 +794,7 @@ def culc_var(arr, ddof, minp): """ Limitations ----------- - Supported ``raw`` only can be `None` or `True`. + Supported ``raw`` only can be `None` or `True`. Parameters ``args``, ``kwargs`` unsupported. Series elements cannot be max/min float/integer. Otherwise SDC and Pandas results are different. """, 'extra_params': From 4d6ddc29370e87c6cc3a60e96c4ef0153acadc51 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 7 Jan 2020 13:48:59 +0300 Subject: [PATCH 10/10] Add test for rolling.apply with args and skip it --- sdc/tests/test_rolling.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sdc/tests/test_rolling.py b/sdc/tests/test_rolling.py index ae9082c6b..e0685e3d3 100644 --- a/sdc/tests/test_rolling.py +++ b/sdc/tests/test_rolling.py @@ -545,6 +545,34 @@ def func(x): msg = 'Method rolling.apply(). The object raw\n given: int64\n expected: bool' self.assertIn(msg, str(raises.exception)) + @unittest.skip('Series.rolling.apply() unsupported args') + def test_series_rolling_apply_args(self): + def test_impl(series, window, min_periods, q): + def func(x, q): + if len(x) == 0: + return np.nan + return np.quantile(x, q) + return series.rolling(window, min_periods).apply(func, raw=None, args=(q,)) + + hpat_func = self.jit(test_impl) + + all_data = [ + list(range(10)), [1., -1., 0., 0.1, -0.1], + [1., np.inf, np.inf, -1., 0., np.inf, np.NINF, np.NINF], + [np.nan, np.inf, np.inf, np.nan, np.nan, np.nan, np.NINF, np.NZERO] + ] + indices = [list(range(len(data)))[::-1] for data in all_data] + for data, index in zip(all_data, indices): + series = pd.Series(data, index, name='A') + for window in range(0, len(series) + 3, 2): + for min_periods in range(0, window + 1, 2): + for q in [0.25, 0.5, 0.75]: + with self.subTest(series=series, window=window, + min_periods=min_periods, q=q): + jit_result = hpat_func(series, window, min_periods, q) + ref_result = test_impl(series, window, min_periods, q) + pd.testing.assert_series_equal(jit_result, ref_result) + @skip_sdc_jit('Series.rolling.corr() unsupported Series index') def test_series_rolling_corr(self): def test_impl(series, window, min_periods, other):