Skip to content

Commit 6cd7572

Browse files
authored
Optimize fmean() weighted average (#102626)
1 parent e621062 commit 6cd7572

File tree

1 file changed

+16
-18
lines changed

1 file changed

+16
-18
lines changed

Lib/statistics.py

+16-18
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@
136136
from decimal import Decimal
137137
from itertools import count, groupby, repeat
138138
from bisect import bisect_left, bisect_right
139-
from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum
139+
from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum, sumprod
140140
from functools import reduce
141-
from operator import mul, itemgetter
141+
from operator import itemgetter
142142
from collections import Counter, namedtuple, defaultdict
143143

144144
_SQRT2 = sqrt(2.0)
@@ -496,28 +496,26 @@ def fmean(data, weights=None):
496496
>>> fmean([3.5, 4.0, 5.25])
497497
4.25
498498
"""
499-
try:
500-
n = len(data)
501-
except TypeError:
502-
# Handle iterators that do not define __len__().
503-
n = 0
504-
def count(iterable):
505-
nonlocal n
506-
for n, x in enumerate(iterable, start=1):
507-
yield x
508-
data = count(data)
509499
if weights is None:
500+
try:
501+
n = len(data)
502+
except TypeError:
503+
# Handle iterators that do not define __len__().
504+
n = 0
505+
def count(iterable):
506+
nonlocal n
507+
for n, x in enumerate(iterable, start=1):
508+
yield x
509+
data = count(data)
510510
total = fsum(data)
511511
if not n:
512512
raise StatisticsError('fmean requires at least one data point')
513513
return total / n
514-
try:
515-
num_weights = len(weights)
516-
except TypeError:
514+
if not isinstance(weights, (list, tuple)):
517515
weights = list(weights)
518-
num_weights = len(weights)
519-
num = fsum(map(mul, data, weights))
520-
if n != num_weights:
516+
try:
517+
num = sumprod(data, weights)
518+
except ValueError:
521519
raise StatisticsError('data and weights must be the same length')
522520
den = fsum(weights)
523521
if not den:

0 commit comments

Comments
 (0)