NumPyには、配列に含まれる要素のデータの散らばり具合を示す指標の1つとなる標準偏差を求める関数があります。

標準偏差とは、データの平均との差を2乗した値の平均に対して平方根をとるものです。この値を計算して標準偏差を調べることで、Jupyter Notebookなどと組み合わせることで簡単にデータ分析をすることができます。

標準偏差に関する詳しい解説は以下のサイトを参照してみてください。

標準偏差とは何か?その求め方や公式の意味・使い方をわかりやすく説明します - アタリマエ!

np.std()

では早速NumPyで実装されている関数np.std()についてみていきます。

APIドキュメント

この関数のAPIドキュメントは以下の通りです。

numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False)

args:

パラメータ名 概要
a array_like
配列に相当するもの
標準偏差を計算したい配列を指定します。
axis Noneもしくはint
もしくはintのタプル
(省略可能)初期値None
どの軸方向に沿って演算を進めていくかを指定します。Noneの場合は全ての要素を対象にして標準偏差を求めます。
dtype データ型 (省略可能)初期値None
演算を行うときに用いるデータ型を指定します。Noneのときは元の配列がintであれば’float64’で、’float’であれば同じデータ型を用います。
out ndarray (省略可能)初期値None
結果を格納する配列を指定します。
ddof int (省略可能)初期値0
標準偏差を計算する際にデータの個数で割り算を行う際、本来のデータの個数Nではなく”N-ddof”で割るようにします。これによってデータの自由度が増加します。
keepdims bool値 (省略可能)初期値False
ここをTrueにしておくと出力される配列の次元数が保存されます。Falseの場合は特に次元が保存されることはありません。要素が1になった次元は削除されます。

returns:

指定された範囲での標準偏差を要素とする配列、または値が出力されます。

引数は、第一引数であるaで標準偏差を求めたい元の配列を指定し、第二引数であるaxisでどの軸方向に演算を行なっていくかを指定します。ちなみにaxisがNoneの場合は全ての軸を選択している状態となっています。 axisの扱いにまだ慣れていないという人は以下の記事を参考にしてみてください。

NumPyの軸(axis)と次元数(ndim)とは何を意味するのか - DeepAge /features/numpy-axis.html

dtypeでは演算に用いるデータ型を指定し、outでは結果を格納する場所を指定する引数ですが、実際にはほとんど使用されることはありません。ddofは統計では重要な役割を果たす引数です。主に不偏標準偏差を求める際にddof=1として使われます。これについての詳しい解説は以下のサイトでされているので参考にしてみてください。

不偏標準偏差

最後にkeepdimsですが、これは元の配列の次元数を保持した状態で結果を出力するかどうかを指定できる引数です。

サンプルコード

実際に使っていきます。まずはシンプルな使い方から。

In [1]: import numpy as np

In [2]: a = np.random.rand(10) # まずは乱数配列をつくる

In [3]: a     # 中身を確かめる
Out[3]:
array([ 0.71939814,  0.5337454 ,  0.70934522,  0.87926569,  0.62625748,
        0.70495854,  0.60617101,  0.91236898,  0.46060223,  0.5032387 ])

In [4]: np.std(a) # 標準偏差を求める
Out[4]: 0.14274293005775698

次は軸(axis)を指定していきます。

In [5]: b = np.random.rand(2,3,4) # 今度は3次元配列を生成。

In [6]: b
Out[6]:
array([[[ 0.98230609,  0.20922622,  0.03297964,  0.18877975],
        [ 0.29958593,  0.21002576,  0.1532091 ,  0.57507757],
        [ 0.56414901,  0.76373121,  0.0430539 ,  0.75423913]],

       [[ 0.66961169,  0.40578786,  0.67082914,  0.23241065],
        [ 0.65127488,  0.29851637,  0.53317126,  0.72906524],
        [ 0.70084795,  0.51023406,  0.35209217,  0.46967969]]])

In [7]: np.std(b, axis=0) # axis=0方向に沿って標準偏差を求める。結果は3×4の2次元配列。
Out[7]:
array([[ 0.1563472 ,  0.09828082,  0.31892475,  0.02181545],
       [ 0.17584447,  0.0442453 ,  0.18998108,  0.07699383],
       [ 0.06834947,  0.12674857,  0.15451914,  0.14227972]])

In [8]: np.std(b, axis=(0, 1)) # 2つ指定するとこの2つの軸方向に広がる平面内における標準偏差を求めてくれる。
Out[8]: array([ 0.20140607,  0.1946228 ,  0.24270338,  0.22049084])

In [9]: np.std(b, axis=(0, 1, 2))
Out[9]: 0.25053597604909356

次はdtypeを指定します。

In [10]: np.std(b, dtype='float16')
Out[10]: 0.25049

In [11]: np.std(b, dtype='complex')
Out[11]: (0.25053597604909356+0j)

outを指定します。データ型と配列の形状(shape)が一致していないとエラーを起こすので注意が必要です。

In [13]: c = np.empty((2,3)) # 受け皿となる配列を用意する。(empty関数を今回は使用)

In [14]: np.std(b, axis=2, out=c) # outでcを指定する。
Out[14]:
array([[ 0.36948544,  0.16198125,  0.29291186],
       [ 0.18595473,  0.1626438 ,  0.12546995]])

In [15]: c # cに値がちゃんと格納されている。
Out[15]:
array([[ 0.36948544,  0.16198125,  0.29291186],
       [ 0.18595473,  0.1626438 ,  0.12546995]])

ddofを指定します。 不偏標準偏差をこれを使って求めてみます。

In [17]: np.std(b) # 元の値(ddof=0)をまず表示する。
Out[17]: 0.25053597604909356

In [18]: np.std(b, ddof=1) # 次にddof=1にして不偏標準偏差を表示させる。
Out[18]: 0.25592446296216997

最後にkeepdimsです。次元数を保持するかどうかを指定します。ここをTrueにしておくとそのままブロードキャスティング機能を利用することができます。 ブロードキャストについては以下の記事で詳しく解説してありますので、気になる方は参照してみてください。

NumPyのブロードキャストのメリットと解説 - DeepAge /featuers/numpy-broadcasting.html

In [19]: np.std(b, keepdims=True) # keepdims=Trueにすると3次元配列が返される。
Out[19]: array([[[ 0.25053598]]])

In [20]: np.std(b, axis=0, keepdims=True) # axisを指定する。
Out[20]:
array([[[ 0.1563472 ,  0.09828082,  0.31892475,  0.02181545],
        [ 0.17584447,  0.0442453 ,  0.18998108,  0.07699383],
        [ 0.06834947,  0.12674857,  0.15451914,  0.14227972]]])


In [22]: b / np.std(b, axis=0, keepdims=True) # このようにブロードキャスティングが適用できる。
Out[22]:
array([[[  6.28285069,   2.12886113,   0.10340884,   8.65348871],
        [  1.70369829,   4.74684886,   0.80644403,   7.46913803],
        [  8.25389003,   6.02556059,   0.27863151,   5.3011008 ]],

       [[  4.28285069,   4.12886113,   2.10340884,  10.65348871],
        [  3.70369829,   6.74684886,   2.80644403,   9.46913803],
        [ 10.25389003,   4.02556059,   2.27863151,   3.3011008 ]]])

In [23]: b / np.std(b, axis=0, keepdims=False) # Falseにしてもうまくいく場合がある。
Out[23]:
array([[[  6.28285069,   2.12886113,   0.10340884,   8.65348871],
        [  1.70369829,   4.74684886,   0.80644403,   7.46913803],
        [  8.25389003,   6.02556059,   0.27863151,   5.3011008 ]],

       [[  4.28285069,   4.12886113,   2.10340884,  10.65348871],
        [  3.70369829,   6.74684886,   2.80644403,   9.46913803],
        [ 10.25389003,   4.02556059,   2.27863151,   3.3011008 ]]])

In [24]: b / np.std(b, axis=1, keepdims=False) # axisを他のものにするとエラーが返ってくることがある。
---------------------------------------------------------------------------
(エラーメッセージが表示される)
ValueError: operands could not be broadcast together with shapes (2,3,4) (2,4)

参考サイト

numpy.std — NumPy v1.13 Manual - Numpy and Scipy Documentation