You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
statistics.stdev() raises AttributeError when data contains infinity #140938
statistics.stdev() crashes when processing data containing inf, while statistics.variance() handles the same input correctly. This violates the invariant stdev = sqrt(variance).
importstatisticsdata= [1.0, 2.0, float('inf'), 4.0, 5.0]
# Works fineprint(statistics.variance(data)) # Returns: inf# Crashesstatistics.stdev(data) # AttributeError: 'float' object has no attribute 'numerator'
inf
Traceback (most recent call last):
File "/data/src/test.py", line 9, in <module>
statistics.stdev(data) # AttributeError: 'float' object has no attribute 'numerator'
^^^^^^^^^^^^^^^^^^^^^^
File "/home/py312/lib/python3.12/statistics.py", line 974, in stdev
return _float_sqrt_of_frac(mss.numerator, mss.denominator)
^^^^^^^^^^^^^
AttributeError: 'float' object has no attribute 'numerator'
I'm not sure statistics.variance is even remotely correct here. For instance, if we consider the mean of the sample as simply being the averaged sum, it would be $\infty$. So, statistics.variance(data, float('inf')) == statistics.variance(data), which is not the case. The first one gives nan while the second returns $\infty$ but the second argument is meant to be the known mean, so we already have inconsistencies.
@rhettinger Was statistics ever meant to handle infinite values in data points? I see that geometric_mean handles NaN inputs but that's the only function that does so.
A case could be made that the variance and standard deviation functions should return a Decimal('NaN') or math.nan if there are one or more positive of negative infinities in the input. The concepts of variance and standard deviation are all about differences from the mean. When you difference infinities, you get a NaN.
@@ -1530,7 +1530,8 @@ def _ss(data, c=None):
elif None in sx_partials:
# The sum will be a NAN or INF. We can ignore all the finite
# partials, and just look at this special one.
- ssd = c = sx_partials[None]+ c = sx_partials[None]+ ssd = type(c)('nan')
assert not _isfinite(ssd)
Also, the downstream functions would need a try/except to handle the non-Fraction return.
Was statistics ever meant to handle infinite values in data points?
Some effort was made to handle infinities but the effort was not thorough.
I would like to see this one fixed but don't want to go fuzzing every function. A decade of deployment revealed that this isn't something users cared about.
i LOL the github UI, I think i just left comments directly on rhettinger@0d6d50c#r170488297 - regardless, add some text to the ValueError indicating that an inf or nan was encountered. and cover nan in the unittest. otherwise, looks good overall.
Activity
picnixz commentedon Nov 3, 2025
I'm not sure$\infty$ . So, $\infty$ but the second argument is meant to be the known mean, so we already have inconsistencies.
statistics.varianceis even remotely correct here. For instance, if we consider the mean of the sample as simply being the averaged sum, it would bestatistics.variance(data, float('inf')) == statistics.variance(data), which is not the case. The first one givesnanwhile the second returns@rhettinger Was
statisticsever meant to handle infinite values in data points? I see thatgeometric_meanhandles NaN inputs but that's the only function that does so.skirpichev commentedon Nov 3, 2025
Perhaps, just this:
T90REAL commentedon Nov 3, 2025
statistics.pstdev()also has this issue, and it could be solved in the same way.rhettinger commentedon Nov 5, 2025
A case could be made that the variance and standard deviation functions should return a
Decimal('NaN')ormath.nanif there are one or more positive of negative infinities in the input. The concepts of variance and standard deviation are all about differences from the mean. When you difference infinities, you get a NaN.Also, the downstream functions would need a try/except to handle the non-Fraction return.
@picnixz
Some effort was made to handle infinities but the effort was not thorough.
I would like to see this one fixed but don't want to go fuzzing every function. A decade of deployment revealed that this isn't something users cared about.
rhettinger commentedon Nov 6, 2025
After more thought, it is even less clear what the correct result should be.
Since
pstdev([x])returns0.0for any value ofx, aninfinput should return0.0as well.However
pstdev([data])is defined assqrt(sum((x - mean(data))**2 for x in data) / len(data))and that returnsnanwhendata=math.inf.Then again,
pstdev([0, x])returnsx / 2for any value ofx, so aninfinput should returnmath.inf.A case can be made for any of:
0.0,nan, andinf.It may be reasonable to replace the
AttributeErrorwith:ValueError('stdev() inputs must be finite').gpshead commentedon Nov 11, 2025
A
ValueErrorwas my first thought as well.pythongh-140938: Raise ValueError for infinite inputs to stdev/pstdev
gpshead commentedon Nov 13, 2025
i LOL the github UI, I think i just left comments directly on rhettinger@0d6d50c#r170488297 - regardless, add some text to the ValueError indicating that an inf or nan was encountered. and cover nan in the unittest. otherwise, looks good overall.
gh-140938: Raise ValueError for infinite inputs to stdev/pstdev (GH-1…
pythongh-140938: Raise ValueError for infinite inputs to stdev/pstdev (…
[3.14] gh-140938: Raise ValueError for infinite inputs to stdev/pstdev (
pythongh-140938: Raise ValueError for infinite inputs to stdev/pstdev (…
gpshead commentedon Nov 15, 2025
thanks for the report and fix!
[3.13] gh-140938: Raise ValueError for infinite inputs to stdev/pstdev (
pythongh-140938: Raise ValueError for infinite inputs to stdev/pstdev (…