Python statistics.fmean()の使い方|mean()との違いとweightsで重み付き平均を求める方法

statistics.fmean()は、データをすべてfloatに変換して平均を求めるPython標準ライブラリの関数です。mean()より速く、戻り値は常にfloatで、Python 3.11以降はweights引数で重み付き平均(加重平均)も計算できます。

この記事では、fmean()とmean()の違い(型・速さ・精度)、weightsを使った加重平均の書き方、バージョンによって動かないケースを、実際に動かした結果つきでまとめます。実行環境はPython 3.12.15と3.9.6です(2026年10月18日確認)。普通の平均の求め方から知りたい方は「Python statistics.mean()とは?平均値を求める方法」を先に読むとスムーズです。

fmean()の基本的な使い方

import statistics

print(statistics.fmean([10, 20, 30, 40]))
print(statistics.mean([10, 20, 30, 40]))
print(statistics.fmean([3.5, 4.0, 5.25]))

実行結果:

25.0
25
4.25

同じデータでも、mean()は整数の25、fmean()はfloatの25.0を返します。fmean()は入力が整数でも必ずfloatを返す、と覚えておけば迷いません。

引数はリストだけでなく、タプルやジェネレーターなど繰り返し取り出せるものなら何でも渡せます。

import statistics

scores = (x * 10 for x in range(1, 6))   # ジェネレーター
print(statistics.fmean(scores))
print(statistics.fmean([1, 2, float('nan')]))

実行結果:

30.0
nan

データにnan(欠損値)が混ざっていると、結果もnanになります。エラーにはならないので、CSVなどから読み込んだデータは先に欠損を取り除いてください。

weightsで重み付き平均(加重平均)を求める

Python 3.11で、fmean()にweights引数が追加されました。公式ドキュメントの例と同じ、成績の重み付けで試します(Python公式ドキュメント statistics、2026年10月18日確認)。

import statistics

grades  = [85, 92, 83, 91]          # 小テスト・課題・中間・期末
weights = [0.20, 0.20, 0.30, 0.30]
print(statistics.fmean(grades, weights))

# 重みは合計が1でなくてもよい(件数などをそのまま渡せる)
prices = [120, 150, 100]   # 店ごとの単価
counts = [30, 10, 60]      # 販売数
print(statistics.fmean(prices, counts))
print(sum(p * c for p, c in zip(prices, counts)) / sum(counts))

実行結果(Python 3.12):

87.6
111.0
111.0

重みは割合でなくても構いません。販売数のような件数をそのまま渡すと、「値×重みの合計÷重みの合計」が計算されます。最後の行のように自分で計算した結果と一致します。

Python 3.10以前では動かない

同じコードをPython 3.9で実行すると、次のエラーになります。

TypeError: fmean() takes 1 positional argument but 2 were given

古い環境も対象にするなら、上の最後の行のようにsum()で計算するか、NumPyのnp.average(data, weights=...)を使います。

重みの数が合わないとValueError

import statistics
try:
    statistics.fmean([1, 2, 3], [1, 2])
except ValueError as e:
    print("ValueError:", e)
try:
    statistics.fmean([])
except statistics.StatisticsError as e:
    print("StatisticsError:", e)

実行結果:

ValueError: data and weights must be the same length
StatisticsError: fmean requires at least one data point

データと重みの個数が違うとValueError、データが空だとStatisticsErrorです。StatisticsErrorはValueErrorのサブクラスなので、まとめてexcept ValueErrorで受けることもできます。

mean()との速さの違い

import statistics, timeit, sys

setup = "import statistics, random; random.seed(0); data = [random.random() for _ in range(10000)]"
t1 = timeit.timeit("statistics.mean(data)", setup=setup, number=200)
t2 = timeit.timeit("statistics.fmean(data)", setup=setup, number=200)
print(sys.version.split()[0])
print(f"mean : {t1:.3f}秒")
print(f"fmean: {t2:.3f}秒")
print(f"{t1 / t2:.0f}倍")

実行結果(手元のMacでの一例):

3.12.15
mean : 0.404秒
fmean: 0.014秒
28倍

1万件の平均を200回求めたところ、Python 3.12では約28倍、Python 3.9では約18倍の差でした。数値はマシンやバージョンで変わりますが、fmean()のほうが一桁以上速い傾向ははっきり出ます。

速さの理由は、mean()がデータの型を調べてDecimalやFractionなら正確な分数計算を行うのに対し、fmean()は最初からfloatとして計算するためです。

FractionとDecimalはfloatになる

import statistics
from fractions import Fraction
from decimal import Decimal

data = [Fraction(1, 3), Fraction(2, 3), Fraction(1, 3)]
print(statistics.mean(data))
print(statistics.fmean(data))
m = statistics.mean([Decimal('0.10'), Decimal('0.25')])
f = statistics.fmean([Decimal('0.10'), Decimal('0.25')])
print(repr(m), repr(f))

実行結果:

4/9
0.4444444444444444
Decimal('0.175') 0.175

mean()は分数なら分数、DecimalならDecimalのまま返しますが、fmean()はfloatに変えます。金額をDecimalで管理しているプログラムでfmean()を使うと、その時点でfloatの誤差が入り込む余地ができます。金額や分数の正確さが必要な処理ではmean()を使ってください。Decimalへの変換の注意点は「Python Decimalへの変換」でまとめています。

floatの精度はmean()と同じ

import statistics, sys

data = [0.1] * 10
print(sys.version.split()[0])
print("sum/len:", sum(data) / len(data))
print("mean   :", statistics.mean(data))
print("fmean  :", statistics.fmean(data))

実行結果(上:Python 3.9.6、下:Python 3.12.15):

3.9.6
sum/len: 0.09999999999999999
mean   : 0.1
fmean  : 0.1

3.12.15
sum/len: 0.1
mean   : 0.1
fmean  : 0.1

fmean()は速くても雑ではなく、mean()と同じく0.1を返します。なお、Python 3.12からは組み込みのsum()もfloatの足し算をより正確なアルゴリズムで行うようになったため、sum()/len()でも0.1になります(Python公式ドキュメント 組み込み関数 sum()、2026年10月18日確認)。古い記事で見かける「sum/lenだと0.09999…になる」という例は、3.11以前の話です。

mean()・fmean()・NumPyの使い分け

項目 mean() fmean() np.mean()
戻り値の型 入力に合わせる 常にfloat NumPyの数値型
Fraction・Decimal 型を保つ floatに変換 数値計算向きではない
重み付き平均 なし weights(3.11以降) np.average(weights=)
速さ 遅い 速い 配列になっていれば最も速い
追加されたバージョン Python 3.4 Python 3.8 外部ライブラリ
  • 整数・小数の普通のデータ → fmean()
  • 金額のDecimalや分数のFractionで、型を保ちたい → mean()
  • すでにNumPy配列・pandasで処理している → np.mean()やdf.mean()

NumPyでの平均は「np.meanとは?Pythonで平均値を計算する方法を初心者向けに解説」で解説しています。幾何平均・調和平均との違いは「statistics.geometric_mean()」「statistics.harmonic_mean()」を参照してください。

平均や分散などの統計を、機械学習につなげて体系的に学びたい方には、テックジムのAIエンジニア養成コース(16章で機械学習とディープラーニングを学ぶコース)があり、第0章「データ分析入門とデータ可視化」や第6章「AIのための統計学入門」で扱っています。

よくある質問

Q. statistics.fmean()とmean()の違いは何ですか?

fmean()はデータをfloatに変換して計算するため速く、戻り値は常にfloatです。mean()は入力の型を保つため、FractionやDecimalを正確に扱えますが遅くなります。普通の数値ならfmean()で問題ありません。

Q. fmean()で加重平均を計算するには?

Python 3.11以降なら、statistics.fmean(data, weights)のように重みのリストを2つ目の引数に渡します。重みは合計が1でなくてもよく、件数などをそのまま渡せます。Python 3.10以前ではweightsが使えません。

Q. fmean()に空のリストを渡すとどうなりますか?

StatisticsError(fmean requires at least one data point)が出ます。StatisticsErrorはValueErrorのサブクラスなので、except ValueErrorでも受け取れます。

Q. fmean()はどのバージョンから使えますか?

fmean()はPython 3.8で追加されました。weights引数はPython 3.11で追加されています。

まとめ

  • statistics.fmean()はfloatで計算する高速な平均(Python 3.8以降)
  • 戻り値は常にfloat。FractionやDecimalもfloatになる
  • Python 3.11以降はfmean(data, weights)で加重平均が求められる
  • 手元の計測ではmean()より18〜28倍速く、floatの精度はmean()と同じ
  • 型を保ちたいときはmean()、配列で処理しているならNumPy

statisticsモジュールのほかの関数は「Python statistics関数一覧|平均・中央値・分散・標準偏差を計算」にまとめています。

あわせて読みたい

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら