Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Doc/library/statistics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ However, for reading convenience, most of the examples show sorted sequences.

.. function:: fmean(data, weights=None)

Convert *data* to floats and compute the arithmetic mean.
Compute the arithmetic mean as a :class:`float`.

This runs faster than the :func:`mean` function and it always returns a
:class:`float`. The *data* may be a sequence or iterable. If the input
Expand All @@ -183,7 +183,10 @@ However, for reading convenience, most of the examples show sorted sequences.
87.6

If *weights* is supplied, it must be the same length as the *data* or
a :exc:`ValueError` will be raised.
a :exc:`ValueError` will be raised. The values in *data* and *weights*
must have compatible types for multiplication. For example,
:class:`~decimal.Decimal` values cannot be mixed with :class:`float`
or :class:`~fractions.Fraction` values.

.. versionadded:: 3.8

Expand Down
7 changes: 5 additions & 2 deletions Lib/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,17 @@ def mean(data):


def fmean(data, weights=None):
"""Convert data to floats and compute the arithmetic mean.
"""Compute the arithmetic mean as a float.

This runs faster than the mean() function and it always returns a float.
If the input dataset is empty, it raises a StatisticsError.

>>> fmean([3.5, 4.0, 5.25])
4.25

If provided, weights must have the same length as data. The values in
data and weights must have compatible types for multiplication.
Decimals cannot be mixed with floats or fractions.
"""
if weights is None:

Expand Down Expand Up @@ -220,7 +223,7 @@ def fmean(data, weights=None):
if not den:
raise StatisticsError('sum of weights must be non-zero')

return num / den
return float(num) / den


def geometric_mean(data):
Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1932,6 +1932,18 @@ def test_weights(self):
with self.assertRaises(StatisticsError):
fmean(iter([10, 20]), iter([-1, 1])) # sum of weights is zero

def test_decimal_weights(self):
for data, weights in [
([Decimal(2), Decimal(4), Decimal(8)], [1, 2, 1]),
([2, 4, 8], [Decimal(1), Decimal(2), Decimal(1)]),
([Decimal(2), Decimal(4), Decimal(8)],
[Decimal(1), Decimal(2), Decimal(1)]),
]:
with self.subTest(data=data, weights=weights):
result = statistics.fmean(data, weights)
self.assertIs(type(result), float)
self.assertEqual(result, 4.5)


# === Tests for variances and standard deviations ===

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix :func:`statistics.fmean` with compatible
:class:`~decimal.Decimal` data and weights. Clarify that weighted inputs must
have compatible types for multiplication.
Loading