Function: Mean (AM, GM, HM)
- Calculate AM, GM and HM of a numeric vector using the following formula.
Arithmetic Mean (AM)
\[ \large AM = (x_1 + x_2 + ... + x_n)/n = \frac{1}{n}\sum\limits_{i=1}^{n} x_{i}\]
Geometric Mean (GM)
\[ \large GM = \sqrt[n]{(x_1 x_2 ... x_n)} = \left( \prod \limits_{i=1}^{n} x_{i} \right) ^{\frac{1}{n}} \]
Harmonic Mean (HM)
\[ \large HM = \frac{n}{(\frac{1}{x_1} + \frac{1}{x_2} + ... + \frac{1}{x_n})} = \frac{1}{\frac{1}{n}\sum\limits_{i=1}^{n} \frac{1}{x_i}}\]
Functions: Modular approach
Note: The following script is for demonstration only to explain the structure of a function and modular approach to function call.
We are expanding all base functions without any obvious advantages here. A possible optimal version is shown in the next section.
Code
import numpy as np
def fn_n(x, **kwargs):
na_rm = kwargs.get('na_rm', None)
if na_rm:
n = len(x[~np.isnan(x)])
else:
n = len(x)
return(n)
def fn_sum(x, **kwargs):
na_rm = kwargs.get('na_rm', None)
if na_rm:
out = np.nansum(x)
else:
out = np.sum(x)
return(out)
def fn_prod(x, **kwargs):
na_rm = kwargs.get('na_rm', None)
if na_rm:
out = np.nanprod(x)
else:
out = np.prod(x)
return(out)
def fn_suminv(x, **kwargs):
na_rm = kwargs.get('na_rm', None)
if na_rm:
out = np.nansum(1/x)
else:
out = np.sum(1/x)
return(out)
def fn_AM(x, **kwargs):
out = fn_sum(x, **kwargs)/fn_n(x, **kwargs)
return(out)
def fn_GM(x, **kwargs):
out = fn_prod(x, **kwargs)**(1/fn_n(x, **kwargs))
return(out)
def fn_HM(x, **kwargs):
out = fn_n(x, **kwargs)/fn_suminv(x, **kwargs)
return(out)
# fn_nMean
def fn_nMean(x, **kwargs):
n = fn_n(x, **kwargs)
AM = fn_AM(x, **kwargs)
GM = fn_GM(x, **kwargs)
HM = fn_HM(x, **kwargs)
Mean = {'n': n, 'AM': AM, 'GM': GM, 'HM': HM}
return(Mean)
Data
Code
A = np.array([11, 12, np.nan, 14, 15])
Optimal version
We have all base functions available; a possible optimal version of the above function can be written as shown below.
Code
import numpy as np
def fn_Mean(x, na_rm=False):
def fn_n(x, na_rm=False):
if na_rm:
x = x[~np.isnan(x)]
return len(x)
n = fn_n(x, na_rm=na_rm)
AM = np.nanmean(x)
GM = np.exp(np.nanmean(np.log(x)))
HM = 1 / np.nanmean(1 / x)
Mean = {'n': n, 'AM': AM, 'GM': GM, 'HM': HM}
return Mean