From 0ae2b70b209da1dc982612493e2ea18cfeed5ec9 Mon Sep 17 00:00:00 2001 From: kompotmalinowy Date: Thu, 10 Aug 2023 20:14:25 +0200 Subject: [PATCH] OOP aggregations funcitons, Combining two aggregation functions --- README.md | 80 +++++++++++++++------ aggregationslib/aggregations.py | 122 ++++++++++++++++++++++++++++---- 2 files changed, 166 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 6a8ead8..f9956c7 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,36 @@ Means, Aggregation functions... #### Example 1: +```pycon +# example data +data = [0.2, 0.6, 0.7] +# configure function parameters +func1 = A_amn(p=0.5) +# use aggregation funciton +print(func1(data)) + +# Combine two aggregations - arithmetic mean and minimum +func2 = Combine2Aggregations(A_ar(), min) +# use combination of aggregation funciton +print(func2(data)) +``` + +#### Example2: +To get information about aggregation function you can use `__str__()` or '__repr__()' methods. + +```pycon +func1 = A_amn(p=0.5) +print(func1) +>>>A_amn(0.5) + +func2 = Combine2Aggregations(A_ar(), A_md()) +print(func2) +>>>A_armd + +func3 = Combine2Aggregations(A_ar(), A_pw(r=3)) +print(func3.__repr__()) # function parameters are printed in order: func1, func2 +>>>A_arpw(r=3) +``` `exponential(y, r=1)` is given by equation @@ -13,35 +43,41 @@ A_6^{(r)}(x_1,...,x_n)= \frac{1}{r}\ln $$ -# 1 -arithmetic(y) +# A_ar - Arithmetic mean -# 2 -quadratic(y) -# 3 -geometric(y) +# A_qd - Quadratic mean -# 4 -harmonic(y) -# 5 -power(y, r=1) +# A_gm - Geometric mean -# 6 -exponential(y, r=1) -# 7 -lehmer(y, r=0) +# A_hm - Harmonic mean -# 8 -arithmetic_min(y, p=0) -# 9 -arithmetic_max(y, p=0) +# A_pw - Power mean -# 10 -median(y) -# 11 -olimpic(y) \ No newline at end of file +# A_ex, A_ex2, A_ex3 - Exponential mean + + +# A_lm - Lehmer mean + + +# A_amn - Arithmetic minimum mean + + +# A_amx - Arithmetic maximum mean + + +# A_md - Median - ordered weighted aggregation + + +# A_ol - Olimpic aggregation + +# A_oln - Olimpic aggregation +We can specify how many greatest and smallest records remove + +# Combine2Aggregations - Combine aggregation functions +Amn, Amx, Aar , Aex , Amd, +Aow1, Aow1 \ No newline at end of file diff --git a/aggregationslib/aggregations.py b/aggregationslib/aggregations.py index 63b7088..884ac1c 100644 --- a/aggregationslib/aggregations.py +++ b/aggregationslib/aggregations.py @@ -1,9 +1,50 @@ +import itertools import math import numpy as np import re +class A_mn: + """ + Minimum + """ + + def __init__(self): + pass + + def __call__(self, array): + if np.ndim(array) != 1: + raise ValueError("y must be 1 dimensional array") + return np.min(array) + + def __repr__(self): + return f"A_mn()" + + def __str__(self): + return f"A_mn" + + +class A_mx: + """ + Maximum + """ + + def __init__(self): + pass + + def __call__(self, array): + if np.ndim(array) != 1: + raise ValueError("y must be 1 dimensional array") + return np.max(array) + + def __repr__(self): + return f"A_mx()" + + def __str__(self): + return f"A_mx" + + class A_ar: """ Arithmetic mean @@ -359,24 +400,77 @@ def __call__(self, array): def __str__(self): pattern = r'A_(.*?)\(' - params_pattern = r'((.*?)\)' + params_pattern = r'\((.*?)\)' + + agg1 = re.search(pattern, self.__agg1.__repr__()).group(1) + agg2 = re.search(pattern, self.__agg2.__repr__()).group(1) + result = f"A_{agg1}{agg2}({self.__p}" + + agg1_param = re.search(params_pattern, self.__agg1.__str__()) + if agg1_param is not None: + agg1_param = agg1_param.group(1) + result += f", {agg1_param}" + + agg2_param = re.search(params_pattern, self.__agg2.__str__()) + if agg2_param is not None: + agg2_param = agg2_param.group(1) + result += f", {agg2_param}" + result += ")" + return result - agg1 = re.search(pattern, self.__agg1.__str__).group(1) - agg1_param = re.search(params_pattern, self.__agg1.__str__).group(1) + def __repr__(self): + pattern = r'A_(.*?)\(' + params_pattern = r'\((.*?)\)' - agg2 = re.search(pattern, self.__agg2.__str__).group(1) - agg2_param = re.search(params_pattern, self.__agg2.__str__).group(1) + agg1 = re.search(pattern, self.__agg1.__repr__()).group(1) + agg2 = re.search(pattern, self.__agg2.__repr__()).group(1) + result = f"A_{agg1}{agg2}(p={self.__p}" - return f"A_{agg1}{agg2}({agg1_param}, {agg2_param})" + agg1_param = re.search(params_pattern, self.__agg1.__repr__()).group(1) + if agg1_param != "": + result += f", {agg1_param}" - def __repr__(self): - pattern = r'A_(.*?)\(' - params_pattern = r'((.*?)\)' + agg2_param = re.search(params_pattern, self.__agg2.__repr__()).group(1) + if agg2_param != "": + result += f", {agg2_param}" + result += ")" + return result + + +if __name__ == "__main__": + # example data + data = [0.2, 0.6, 0.7] + # configure function parameters + func1 = A_amn(p=0.5) + # use aggregation funciton + print(func1(data)) + + # Combine two aggregations - arithmetic mean and minimum + func2 = Combine2Aggregations(A_ar(), min) + # use combination of aggregation funciton + print(func2(data)) + + func1 = A_amn(p=0.5) + print(func1) + + func2 = Combine2Aggregations(A_ar(), A_md()) + print(func2) + + func3 = Combine2Aggregations(A_ar(), A_pw(r=3)) + print(func3.__repr__()) # function parameters are printed in order: func1, func2 + + aggregation_functions = [] + ex_params = [0.2, 0.5, 1, 2, 3, 5] + for param in ex_params: + aggregation_functions.append(A_ex(param)) - agg1 = re.search(pattern, self.__agg1.__repr__).group(1) - agg1_param = re.search(params_pattern, self.__agg1.__repr__).group(1) + aggregation_functions += [A_mn(), A_mx(), A_ar(), A_md(), + A_ol()] - agg2 = re.search(pattern, self.__agg2.__repr__).group(1) - agg2_param = re.search(params_pattern, self.__agg2.__repr__).group(1) + combinations = [] + for func1, func2 in itertools.combinations(aggregation_functions, 2): + for p in range(1, 10): + combinations.append(Combine2Aggregations(func1, func2, p=p / 10)) - return f"A_{agg1}{agg2}({agg1_param}, {agg2_param})" + for x in combinations: + print(x.__repr__())