12.

NumPyで平均値を求める方法|np.meanのaxisとaverage・nanmeanの違い

編集

Python の数値計算ライブラリ NumPy で平均値を算出するには、np.mean() 関数に配列を渡すだけで実現できます。さらに axis 引数で行ごと・列ごとの平均を求めたり、np.average() で重み付き平均、np.nanmean() で欠損値(NaN)を除いた平均を計算したりと、用途に応じた関数が用意されています。本記事では基本から落とし穴までを最小コードとともに整理します。

 

この記事の要点
  • 最も基本的な平均は np.mean(配列) で求められる。
  • 2次元配列では axis=0 で列ごと、axis=1 で行ごとの平均になる。
  • 重みを付けたい場合は np.average(配列, weights=重み) を使う。
  • NaN を含むデータは np.nanmean() を使えば欠損値を無視して平均できる。
  • 配列.mean() のようにメソッド形式でも呼び出せる。
  • NaN が1つでも混じると np.mean() の結果は NaN になる点に注意。

 

np.mean() の基本

NumPy 配列(ndarray)の全要素の平均値(算術平均)を求める最も基本的な関数が np.mean() です。引数に配列やリストを渡すと、全要素の合計を要素数で割った値を返します。

import numpy as np

 

arr = np.array([1, 2, 3, 4, 5])

print(np.mean(arr))  # 3.0

 

戻り値は浮動小数点数(float)です。たとえ整数だけの配列でも、合計を要素数で割る計算が行われるため結果は実数(上の例では 3.0)になります。Python の標準リストを渡しても内部で配列に変換されて動作しますが、計算対象が NumPy 配列であることを前提とした関数です。

 

axis 引数で行ごと・列ごとの平均を求める

2次元以上の配列では、axis 引数を指定することでどの方向に沿って平均を取るかを制御できます。axis を省略すると全要素の平均(スカラー値)になります。

  • axis=0 … 行方向(縦方向)に集約し、列ごとの平均を返す。
  • axis=1 … 列方向(横方向)に集約し、行ごとの平均を返す。

次の2行3列の配列で挙動を確認します。

import numpy as np

 

arr = np.array([[1, 2, 3],

                [4, 5, 6]])

 

print(np.mean(arr))        # 3.5  (全体)

print(np.mean(arr, axis=0)) # [2.5 3.5 4.5]  (列ごと)

print(np.mean(arr, axis=1)) # [2. 5.]       (行ごと)

 

axis=0 では各列について縦に平均が取られ、1列目は (1+4)/2=2.5、2列目は (2+5)/2=3.5、3列目は (3+6)/2=4.5 となります。axis=1 では各行について横に平均が取られ、1行目は (1+2+3)/3=2.0、2行目は (4+5+6)/3=5.0 となります。「axis に指定した軸が結果から消える(その軸方向に集約される)」と覚えると取り違えを防げます。

 

np.average() との違い(重み付き平均)

np.average() も平均を求める関数ですが、weights 引数で各要素に重みを付けられる点が np.mean() との大きな違いです。weights を指定すると、各要素に重みを掛けた合計を重みの合計で割った重み付き平均(加重平均)を計算します。

import numpy as np

 

scores = np.array([80, 90, 100])

weights = np.array([1, 2, 3])

 

print(np.average(scores, weights=weights))

# (80*1 + 90*2 + 100*3) / (1+2+3) = 560 / 6 = 93.33...

 

weights を省略した np.average()np.mean() と同じ単純平均を返します。両者の主な違いは次の通りです。

  • np.mean() は重み付けに対応せず単純平均のみ。dtype 引数で計算精度を指定できる。
  • np.average()weights による重み付き平均に対応する。returned=True を指定すると平均値と重みの合計をタプルで返す。

重みが不要なら np.mean()、重みを使いたいなら np.average() を選ぶのが基本方針です。

 

欠損値に対応する np.nanmean()

実データには欠損値が np.nan として含まれることがあります。通常の np.mean() は NaN を含む配列に対して結果が NaN になってしまうため、欠損値を無視して平均を取りたい場合は np.nanmean() を使います。

import numpy as np

 

arr = np.array([1, 2, np.nan, 4])

 

print(np.mean(arr))    # nan

print(np.nanmean(arr)) # 2.333... (NaN を除いた1,2,4の平均)

 

np.nanmean() は NaN 以外の要素だけで平均を計算します。axis 引数も np.mean() と同様に使えます。ただし、ある軸方向の要素がすべて NaN だった場合、その箇所の結果は NaN になり警告(RuntimeWarning)が表示されることがあります。

 

ndarray.mean() メソッド形式

平均は関数だけでなく、NumPy 配列(ndarray)の mean() メソッドとしても呼び出せます。np.mean(arr)arr.mean() は同じ結果になり、axis 引数も同様に指定できます。

import numpy as np

 

arr = np.array([[1, 2, 3],

                [4, 5, 6]])

 

print(arr.mean())       # 3.5

print(arr.mean(axis=0)) # [2.5 3.5 4.5]

 

メソッド形式は、すでに配列オブジェクトを変数に持っている場合に記述が簡潔になります。なお、averagenanmean には対応する ndarray メソッドが無いため、これらは関数形式(np.average()np.nanmean())で呼び出します。

 

平均を求める関数の比較

関数・形式 用途 重み付き NaN を無視
np.mean() 基本の単純平均 不可 しない
arr.mean() メソッド形式の単純平均 不可 しない
np.average() 重み付き平均(加重平均) 可(weights) しない
np.nanmean() 欠損値を除いた平均 不可 する

 

よくある落とし穴

注意したいポイント
  • axis の取り違え:「列ごと」が欲しいのに axis=1 を指定してしまうミスが多い。axis=0 が列ごと、axis=1 が行ごと。「指定した軸が集約されて消える」と覚える。
  • NaN 混入で結果が NaN:np.mean() は NaN を含むと結果全体が NaN になる。欠損値があるデータでは np.nanmean() を使う。
  • 整数配列でも結果は float:整数だけの配列でも平均は浮動小数点数で返る。整数で受け取りたい場合は別途丸め処理(np.round など)や型変換が必要。
  • 空配列の平均:要素数 0 の配列に np.mean() を使うと NaN になり警告が出る。事前に要素数を確認すると安全。

 

FAQ

Q. np.mean() と statistics.mean() はどう違いますか?

A. statistics.mean() は Python 標準ライブラリの関数で、リストなどに対する単純平均を返します。NumPy の np.mean() は多次元配列に対応し、axis による行・列ごとの集約や大量データの高速計算が得意です。配列を扱うなら np.mean() が適しています。

 

Q. 平均値を整数で受け取りたい場合はどうすればよいですか?

A. np.mean() は常に浮動小数点数を返すため、結果に対して int() や np.round() を適用して変換します。四捨五入したい場合は np.round(np.mean(arr)) のように組み合わせます。

 

Q. 中央値や合計など、平均以外の集計も同じように求められますか?

A. はい。中央値は np.median()、合計は np.sum()、最大・最小は np.max()・np.min() など、いずれも axis 引数に対応した関数が用意されています。欠損値対応版として np.nanmedian() や np.nansum() も利用できます。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 配列の作成
  2. 多次元配列の作成
  3. 要素の参照
  4. 要素の追加
  5. 要素の更新
  6. 要素の削除
  7. ブロードキャスト
  8. 多次元配列の構造の確認
  9. 多次元配列を1次元配列に変換
  10. 1次元配列を多次元配列に変換
  11. NumPy 配列の範囲指定(スライス・多次元・Boolean / Fancy Index)
  12. 平均値の算出
  13. 行列を結合する方法

最近更新/作成されたページ