diff --git a/hpat/datatypes/hpat_pandas_series_functions.py b/hpat/datatypes/hpat_pandas_series_functions.py index 396fe04df..71bb8c7a8 100644 --- a/hpat/datatypes/hpat_pandas_series_functions.py +++ b/hpat/datatypes/hpat_pandas_series_functions.py @@ -894,6 +894,61 @@ def hpat_pandas_series_pow_impl(self, other): raise TypingError('{} The object must be a pandas.series and argument must be a number. Given: {} and other: {}'.format(_func_name, self, other)) +@overload_method(SeriesType, 'max') +def hpat_pandas_series_max(self, axis=None, skipna=True, level=None, numeric_only=None): + """ + Pandas Series method :meth:`pandas.Series.max` implementation. + + .. only:: developer + + Test: python -m hpat.runtests hpat.tests.test_series.TestSeries.test_series_max + python -m hpat.runtests hpat.tests.test_series.TestSeries.test_series_max_param + + Parameters + ----------- + axis: + *unsupported* + skipna: :obj:`bool` object + Exclude nan values when computing the result + level: + *unsupported* + numeric_only: + *unsupported* + + Returns + ------- + :obj: + returns :obj: scalar + """ + + _func_name = 'Method max().' + + if not isinstance(self, SeriesType): + raise TypingError('{} The object must be a pandas.series. Given: {}'.format(_func_name, self)) + + if not isinstance(self.data.dtype, (types.Integer, types.Float)): + raise TypingError('{} Currently function supports only numeric values. Given data type: {}'.format(_func_name, self.data.dtype)) + + if not isinstance(skipna, (types.Omitted, types.Boolean)) and skipna is not True: + raise TypingError( + '{} The parameter must be a boolean type. Given type skipna: {}'.format(_func_name, skipna)) + + if not (isinstance(axis, types.Omitted) or axis is None) \ + or not (isinstance(level, types.Omitted) or level is None) \ + or not (isinstance(numeric_only, types.Omitted) or numeric_only is None): + raise TypingError( + '{} Unsupported parameters. Given axis: {}, level: {}, numeric_only: {}'.format(_func_name, axis, level, + numeric_only)) + + def hpat_pandas_series_max_impl(self, axis=None, skipna=True, level=None, numeric_only=None): + if skipna: + return numpy.nanmax(self._data) + + return self._data.max() + + return hpat_pandas_series_max_impl + + @overload_method(SeriesType, 'mod') def hpat_pandas_series_mod(self, other, level=None, fill_value=None, axis=0): """ diff --git a/hpat/hiframes/hiframes_typed.py b/hpat/hiframes/hiframes_typed.py index 8662cf94c..c1f799eb0 100644 --- a/hpat/hiframes/hiframes_typed.py +++ b/hpat/hiframes/hiframes_typed.py @@ -853,8 +853,8 @@ def _run_call_series(self, assign, lhs, rhs, series_var, func_name): # single arg functions if func_name in ('sum', 'count', 'mean', 'var', 'min', 'max', 'prod'): if rhs.args or rhs.kws: - raise ValueError("unsupported Series.{}() arguments".format( - func_name)) + raise ValueError("HPAT pipeline does not support arguments for Series.{}()".format(func_name)) + # TODO: handle skipna, min_count arguments series_typ = self.typemap[series_var.name] series_dtype = series_typ.dtype diff --git a/hpat/hiframes/pd_series_ext.py b/hpat/hiframes/pd_series_ext.py index 2f2a101e4..2b90ca441 100644 --- a/hpat/hiframes/pd_series_ext.py +++ b/hpat/hiframes/pd_series_ext.py @@ -700,13 +700,13 @@ def resolve_idxmax(self, ary, args, kws): assert not kws return signature(types.intp, *args) - @bound_function("series.max") - def resolve_max(self, ary, args, kws): - assert not kws - dtype = ary.dtype - dtype = (pandas_timestamp_type - if isinstance(dtype, types.NPDatetime) else dtype) - return signature(dtype, *args) + # @bound_function("series.max") + # def resolve_max(self, ary, args, kws): + # assert not kws + # dtype = ary.dtype + # dtype = (pandas_timestamp_type + # if isinstance(dtype, types.NPDatetime) else dtype) + # return signature(dtype, *args) @bound_function("series.min") def resolve_min(self, ary, args, kws): @@ -986,7 +986,8 @@ def generic_expand_cumulative_series(self, args, kws): install_array_method(fname, generic_expand_cumulative_series) # TODO: add itemsize, strides, etc. when removed from Pandas -_not_series_array_attrs = ['flat', 'ctypes', 'itemset', 'reshape', 'sort', 'flatten', 'resolve_take'] +_not_series_array_attrs = ['flat', 'ctypes', 'itemset', 'reshape', 'sort', 'flatten', + 'resolve_take', 'resolve_max'] # use ArrayAttribute for attributes not defined in SeriesAttribute for attr, func in numba.typing.arraydecl.ArrayAttribute.__dict__.items(): diff --git a/hpat/tests/test_join.py b/hpat/tests/test_join.py index 7a86e03d8..017affacc 100644 --- a/hpat/tests/test_join.py +++ b/hpat/tests/test_join.py @@ -173,6 +173,7 @@ def test_impl(df1, df2): ['2017-01-01', '2017-01-06', '2017-01-03']), 'A': [7, 8, 9]}) pd.testing.assert_frame_equal(hpat_func(df1, df2), test_impl(df1, df2)) + @unittest.skip("Method max(). Currently function supports only numeric values. Given data type: datetime64[ns]") def test_join_datetime_parallel1(self): def test_impl(df1, df2): df3 = pd.merge(df1, df2, on='time') @@ -207,6 +208,7 @@ def test_impl(df1, df2): '2017-02-25']), 'A': [2, 3, 7, 8, 9]}) pd.testing.assert_frame_equal(hpat_func(df1, df2), test_impl(df1, df2)) + @unittest.skip("Method max(). Currently function supports only numeric values. Given data type: datetime64[ns]") def test_merge_asof_parallel1(self): def test_impl(): df1 = pd.read_parquet('asof1.pq') diff --git a/hpat/tests/test_series.py b/hpat/tests/test_series.py index 6e64fa404..5d2bec99e 100644 --- a/hpat/tests/test_series.py +++ b/hpat/tests/test_series.py @@ -916,13 +916,35 @@ def test_impl(S): S = pd.Series([np.nan, 2., 3.]) self.assertEqual(hpat_func(S), test_impl(S)) - def test_series_max1(self): + def test_series_max(self): def test_impl(S): return S.max() hpat_func = hpat.jit(test_impl) - S = pd.Series([np.nan, 2., 3.]) - self.assertEqual(hpat_func(S), test_impl(S)) + # TODO type_min/type_max + for input_data in [[np.nan, 2., np.nan, 3., np.inf, 1, -1000], + [8, 31, 1123, -1024], + [2., 3., 1, -1000, np.inf]]: + S = pd.Series(input_data) + + result_ref = test_impl(S) + result = hpat_func(S) + self.assertEqual(result, result_ref) + + @unittest.skipIf(hpat.config.config_pipeline_hpat_default, "Series.max() any parameters unsupported") + def test_series_max_param(self): + def test_impl(S, param_skipna): + return S.max(skipna=param_skipna) + + hpat_func = hpat.jit(test_impl) + + for input_data, param_skipna in [([np.nan, 2., np.nan, 3., 1, -1000, np.inf], True), + ([2., 3., 1, np.inf, -1000], False)]: + S = pd.Series(input_data) + + result_ref = test_impl(S, param_skipna) + result = hpat_func(S, param_skipna) + self.assertEqual(result, result_ref) def test_series_value_counts(self): def test_impl(S):