Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python : easy way to do geometric mean in python?

People also ask

What is the easiest way to calculate geometric mean?

To calculate the geometric mean of two numbers, you would multiply the numbers together and take the square root of the result.

How do you find the mean in Python?

mean() function can be used to calculate mean/average of a given list of numbers. It returns mean of the data set passed as parameters. Arithmetic mean is the sum of data divided by the number of data-points. It is a measure of the central location of data in a set of values which vary in range.


The formula of the gemetric mean is:

geometrical mean

So you can easily write an algorithm like:

import numpy as np

def geo_mean(iterable):
    a = np.array(iterable)
    return a.prod()**(1.0/len(a))

You do not have to use numpy for that, but it tends to perform operations on arrays faster than Python. See this answer for why.

In case the chances of overflow are high, you can map the numbers to a log domain first, calculate the sum of these logs, then multiply by 1/n and finally calculate the exponent, like:

import numpy as np

def geo_mean_overflow(iterable):
    return np.exp(np.log(iterable).mean())

In case someone is looking here for a library implementation, there is gmean() in scipy, possibly faster and numerically more stable than a custom implementation:

>>> from scipy.stats.mstats import gmean
>>> gmean([1.0, 0.00001, 10000000000.])
46.415888336127786

Compatible with both Python 2 and 3.*


Starting Python 3.8, the standard library comes with the geometric_mean function as part of the statistics module:

from statistics import geometric_mean

geometric_mean([1.0, 0.00001, 10000000000.]) // 46.415888336127786

Here's an overflow-resistant version in pure Python, basically the same as the accepted answer.

import math

def geomean(xs):
    return math.exp(math.fsum(math.log(x) for x in xs) / len(xs))

just do this:

numbers = [1, 3, 5, 7, 10]


print reduce(lambda x, y: x*y, numbers)**(1.0/len(numbers))