np.nanvarとは?NumPyでNaNを無視して分散を計算する方法

PythonでNumPyを使ってデータ分析をしていると、データの中にNaN(欠損値)が含まれていることがあります。

通常のnp.var()ではNaNが含まれていると結果もNaNになってしまいます。このような場合に便利なのがnp.nanvar()です。

np.nanvar()は、NaNを無視して分散を計算する関数です。(NumPy)

この記事では、np.nanvar()の基本的な使い方から、np.var()との違い、axisやddofの指定方法まで、Python初心者向けに解説します。

np.nanvarとは

np.nanvar()は、NumPyでNaNを除外して分散を計算する関数です。

基本的な書き方は次のとおりです。

import numpy as np

np.nanvar(配列)

例えば、次のようなデータがあるとします。

import numpy as np

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

print(np.nanvar(data))

実行すると、

2.5

となります。

np.nanvar()はnp.nanを計算対象から除外して、1、2、4、5の4個のデータから分散を計算します。(NumPy)


そもそも分散とは?

分散とは、データが平均値からどのくらい離れているかを表す値です。

例えば、

1, 2, 3, 4, 5

のようなデータを考えます。

平均値は、

3

です。

それぞれの値が平均からどの程度離れているかを使って、データのばらつきを数値化したものが分散です。

NumPyでは通常、

np.var()

を使って分散を計算できます。

一方、NaNを含むデータでは、

np.nanvar()

を使います。


np.var()とnp.nanvar()の違い

np.var()とnp.nanvar()の違いを確認してみましょう。

import numpy as np

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

print(np.var(data))
print(np.nanvar(data))

結果は、

nan
2.5

となります。

np.var()はNaNを含むため、結果もNaNになります。

一方、

np.nanvar(data)

ではNaNを無視して分散を計算します。(NumPy)

使い分け

関数 NaNの扱い
np.var() NaNがあると結果もNaN
np.nanvar() NaNを無視して計算

欠損値を含むデータの分散を計算するときは、np.nanvar()が便利です。


np.nanvar()の基本的な使い方

1次元配列で使う

最も基本的な使い方です。

import numpy as np

data = np.array([10, 20, 30, 40, 50])

result = np.nanvar(data)

print(result)

NaNがない通常の配列でも使用できます。


NaNを含む配列で使う

np.nanvar()が特に便利なのは、NaNを含むデータです。

import numpy as np

data = np.array([10, 20, np.nan, 40, 50])

result = np.nanvar(data)

print(result)

この場合、np.nanを無視して、

10, 20, 40, 50

の分散を計算します。


2次元配列でnp.nanvar()を使う

2次元配列にも使用できます。

import numpy as np

data = np.array([
    [1, 2, np.nan],
    [4, 5, 6]
])

print(np.nanvar(data))

axisを指定しない場合、配列全体を対象に分散を計算します。

NumPyの公式ドキュメントでも、axis=Noneの場合は配列を平坦化して分散を計算すると説明されています。(NumPy)


np.nanvar()でaxisを指定する

axisを指定すると、行や列ごとに分散を計算できます。

例えば、

import numpy as np

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

print(np.nanvar(data, axis=0))

結果は、

[1. 1. 0.]

となります。

axis=0では、列方向に分散を計算します。

axis=1の場合

print(np.nanvar(data, axis=1))

結果は、

[0.25 0.66666667]

となります。

axis=1では、それぞれの行について分散を計算します。

公式ドキュメントでも、axis=0やaxis=1を指定して分散を計算する例が掲載されています。(NumPy)


np.nanvar()のddofとは?

np.nanvar()にはddofという引数があります。

np.nanvar(data, ddof=1)

ddofは自由度調整に使用される値です。

デフォルトでは、

ddof=0

です。

分散の計算では、データ数をNとすると、ddofを指定した場合の分母は、

N - ddof

になります。(NumPy)

ddof=0

import numpy as np

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

print(np.nanvar(data))

デフォルトでは、

ddof=0

として計算されます。

ddof=1

print(np.nanvar(data, ddof=1))

統計処理などで標本分散を求める場合には、ddof=1を使用することがあります。


NaNが複数ある場合

np.nanvar()では、複数のNaNがあってもNaNを無視して計算できます。

import numpy as np

data = np.array([
    10,
    np.nan,
    20,
    np.nan,
    30
])

print(np.nanvar(data))

計算対象になるのは、

10, 20, 30

です。

つまり、NaNが欠損値として入っているデータを、そのまま分散計算に利用できます。


すべてNaNの場合はどうなる?

注意したいのが、すべての値がNaNの場合です。

import numpy as np

data = np.array([np.nan, np.nan, np.nan])

print(np.nanvar(data))

このような場合、計算できるデータが存在しないため、結果はNaNになります。

また、RuntimeWarningが発生します。NumPy公式ドキュメントでも、すべてがNaNのスライスや自由度が0になる場合はNaNを返し、RuntimeWarningを発生させると説明されています。(NumPy)


np.nanvar()とnp.nanstd()の違い

NumPyには、

np.nanvar()

のほかに、

np.nanstd()

という関数もあります。

違いは、計算する値です。

関数 内容
np.nanvar() NaNを無視して分散を計算
np.nanstd() NaNを無視して標準偏差を計算

例えば、

import numpy as np

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

print(np.nanvar(data))
print(np.nanstd(data))

となります。

分散と標準偏差は関連しています。

標準偏差 = √分散

そのため、ばらつきを分散で扱いたい場合はnp.nanvar()、標準偏差で扱いたい場合はnp.nanstd()を使います。(NumPy)


np.nanvar()でよく使う引数

np.nanvar()では、主に次の引数を使用します。

np.nanvar(
    a,
    axis=None,
    dtype=None,
    out=None,
    ddof=0,
    keepdims=False
)

現在のNumPyでは、さらにwhere、mean、correctionなどの引数も利用できます。(NumPy)

a

分散を計算する配列です。

np.nanvar(data)

axis

分散を計算する方向を指定します。

np.nanvar(data, axis=0)

dtype

計算に使用するデータ型を指定します。

np.nanvar(data, dtype=np.float64)

特にfloat32などの浮動小数点データでは、より高い精度のdtypeを指定することで計算精度を改善できる場合があります。(NumPy)

ddof

自由度調整を指定します。

np.nanvar(data, ddof=1)

デフォルトは0です。

keepdims

Trueにすると、計算した軸をサイズ1の次元として残します。

np.nanvar(data, axis=1, keepdims=True)

元の配列と結果をブロードキャストしたい場合などに便利です。(NumPy)


np.nanvar()を使うメリット

np.nanvar()を使うメリットは、欠損値を含むデータを前処理せずに分散計算できることです。

例えば、売上データやセンサーデータなどに欠損値が含まれている場合、

data = np.array([100, 120, np.nan, 110, 130])

のようなデータが発生することがあります。

このとき、

np.var(data)

ではNaNになってしまいます。

しかし、

np.nanvar(data)

なら、NaNを除外して分散を計算できます。


np.nanvar()を使うときの注意点

NaNが存在しない場合

NaNがないデータでは、

np.nanvar(data)

と

np.var(data)

は基本的に同じ分散を計算します。


NaNを「0」として扱うわけではない

重要なのは、np.nanvar()がNaNを0に置き換えているわけではないことです。

例えば、

[1, 2, np.nan, 4]

に対して、np.nanvar()は、

[1, 2, 4]

を対象として計算します。

つまり、NaNを計算対象から除外する関数です。


NaNだけのデータには注意

次のようなデータでは、

[np.nan, np.nan]

計算対象がないため、分散を求められません。

結果はNaNになるため、データ分析では事前に欠損データの状態を確認しておくことも重要です。(NumPy)


まとめ

np.nanvar()は、NumPyでNaNを無視して分散を計算する関数です。

基本的な使い方は、

import numpy as np

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

result = np.nanvar(data)

print(result)

です。

覚えておきたいポイントは次のとおりです。

  • np.nanvar()はNaNを無視して分散を計算する

  • np.var()はNaNを含むと結果がNaNになる

  • axisで行・列ごとの分散を計算できる

  • ddof=1などで自由度を調整できる

  • np.nanstd()はNaNを無視して標準偏差を計算する

  • すべてNaNのデータでは結果がNaNになる

  • 欠損値を含むデータの統計処理に便利

特に、欠損値を含む実データのばらつきを計算するときにnp.nanvar()は便利な関数です。(NumPy)

メタディスクリプション:
PythonのNumPyにあるnp.nanvar()について初心者向けに解説。NaNを無視して分散を計算する方法、np.var()との違い、axis、ddof、keepdimsの使い方をサンプルコード付きで紹介します。


NumPy|数学・統計の関連記事

平均・分散などの統計量や、数学関数に関する記事です。

NumPy全体の使い方は「NumPyの使い方」、「NumPy関数一覧」でまとめています。

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

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