From 126fd317c837047dcdb6a84d1ffcc6c3869130f2 Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 23 Dec 2019 16:38:57 +0300 Subject: [PATCH 1/2] Overload series.rolling.kurt() --- .../series/rolling/series_rolling_kurt.py | 39 ++++++++++++++ .../hpat_pandas_series_rolling_functions.py | 52 +++++++++++++++++++ sdc/tests/test_rolling.py | 19 +++++++ 3 files changed, 110 insertions(+) create mode 100644 examples/series/rolling/series_rolling_kurt.py diff --git a/examples/series/rolling/series_rolling_kurt.py b/examples/series/rolling/series_rolling_kurt.py new file mode 100644 index 000000000..1eefa0b4e --- /dev/null +++ b/examples/series/rolling/series_rolling_kurt.py @@ -0,0 +1,39 @@ +# ***************************************************************************** +# 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 pandas as pd +from numba import njit + + +@njit +def series_rolling_kurt(): + series = pd.Series([4, 3, 5, 2, 6]) # Series of 4, 3, 5, 2, 6 + out_series = series.rolling(4).kurt() + + return out_series # Expect series of NaN, NaN, NaN, -1.2, -3.3 + + +print(series_rolling_kurt()) \ No newline at end of file diff --git a/sdc/datatypes/hpat_pandas_series_rolling_functions.py b/sdc/datatypes/hpat_pandas_series_rolling_functions.py index 918c8254f..f78f4afe3 100644 --- a/sdc/datatypes/hpat_pandas_series_rolling_functions.py +++ b/sdc/datatypes/hpat_pandas_series_rolling_functions.py @@ -99,6 +99,31 @@ def arr_corr(x, y): return numpy.corrcoef(x, y)[0, 1] +@register_jitable +def _moment(arr, moment): + mn = numpy.mean(arr) + s = numpy.power((arr - mn), moment) + + return numpy.mean(s) + + +@register_jitable +def arr_kurt(arr): + """Calculate unbiased kurtosis of values""" + n = len(arr) + if n < 4: + return numpy.nan + + m2 = _moment(arr, 2) + m4 = _moment(arr, 4) + val = 0 if m2 == 0 else m4 / m2 ** 2.0 + + if (n > 2) & (m2 > 0): + val = 1.0/(n-2)/(n-3) * ((n**2-1.0)*m4/m2**2.0 - 3*(n-1)**2.0) + + return val + + @register_jitable def arr_max(arr): """Calculate maximum of values""" @@ -221,6 +246,8 @@ def impl(self): hpat_pandas_rolling_series_count_impl = register_jitable( gen_hpat_pandas_series_rolling_zerominp_impl(arr_nonnan_count, float64)) +hpat_pandas_rolling_series_kurt_impl = register_jitable( + gen_hpat_pandas_series_rolling_impl(arr_kurt, float64)) hpat_pandas_rolling_series_max_impl = register_jitable( gen_hpat_pandas_series_rolling_impl(arr_max, float64)) hpat_pandas_rolling_series_mean_impl = register_jitable( @@ -355,6 +382,15 @@ def hpat_pandas_series_rolling_count(self): return hpat_pandas_rolling_series_count_impl +@sdc_overload_method(SeriesRollingType, 'kurt') +def hpat_pandas_series_rolling_kurt(self): + + ty_checker = TypeChecker('Method rolling.kurt().') + ty_checker.check(self, SeriesRollingType) + + return hpat_pandas_rolling_series_kurt_impl + + @sdc_overload_method(SeriesRollingType, 'max') def hpat_pandas_series_rolling_max(self): """ @@ -666,6 +702,22 @@ def culc_var(arr, ddof, minp): """ }) +hpat_pandas_series_rolling_kurt.__doc__ = hpat_pandas_series_rolling_docstring_tmpl.format(**{ + 'method_name': 'kurt', + 'example_caption': 'Calculate unbiased rolling kurtosis.', + 'example_result': + """ + 0 NaN + 1 NaN + 2 NaN + 3 -1.2 + 4 -3.3 + dtype: float64 + """, + 'limitations_block': '', + 'extra_params': '' +}) + 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.', diff --git a/sdc/tests/test_rolling.py b/sdc/tests/test_rolling.py index bbdaec123..4480f7629 100644 --- a/sdc/tests/test_rolling.py +++ b/sdc/tests/test_rolling.py @@ -578,6 +578,25 @@ def test_impl(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.kurt() unsupported Series index') + def test_series_rolling_kurt(self): + def test_impl(series, window, min_periods): + return series.rolling(window, min_periods).kurt() + + hpat_func = self.jit(test_impl) + + all_data = test_global_input_data_float64 + 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(4, len(series) + 1): + for min_periods in range(window + 1): + with self.subTest(series=series, window=window, + min_periods=min_periods): + ref_result = test_impl(series, window, min_periods) + jit_result = hpat_func(series, window, min_periods) + pd.testing.assert_series_equal(jit_result, ref_result) + @skip_sdc_jit('Series.rolling.max() unsupported Series index') def test_series_rolling_max(self): def test_impl(series, window, min_periods): From 19a8d1214ca81978185234b044a0d2886481328c Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 23 Dec 2019 16:42:16 +0300 Subject: [PATCH 2/2] Minor fixes foir series.rolling.kurt() --- examples/series/rolling/series_rolling_kurt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/series/rolling/series_rolling_kurt.py b/examples/series/rolling/series_rolling_kurt.py index 1eefa0b4e..5010ae1f6 100644 --- a/examples/series/rolling/series_rolling_kurt.py +++ b/examples/series/rolling/series_rolling_kurt.py @@ -36,4 +36,4 @@ def series_rolling_kurt(): return out_series # Expect series of NaN, NaN, NaN, -1.2, -3.3 -print(series_rolling_kurt()) \ No newline at end of file +print(series_rolling_kurt())