NumPy配列の要素の合計を求めるsum関数の使い方

NumPyのsum関数は、指定の軸に沿って配列の合計値を求める関数です。ここでは、その使い方について解説していきます。なお同じ機能を持つメソッドにndarray.sumがあります。これについても解説します。それでは、早速見ていきましょう。

NumPy配列の合計・和を取得する操作まとめ
配列の合計値の操作に関しては、『NumPyの合計・和を取得する関数とメソッドまとめ』ですべて簡潔にまとめています。ぜひご確認ください。

目次

1. 書式

まずは、書き方を確認しましょう。

ご覧頂く通り、np.sumには多くのオプション引数があります。しかし全てを一度に理解しようとする必要はありません。最もよく使うのは axis なので、まずはこれを抑えておきましょう。他には initial, keepdims 辺りを優先的に抑えておくと良いでしょう。

numpy.sum

書き方:

np.sum(a, axis=None, dtype=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)

※コードが見切れています。お手数ですが右にスライドしてご確認ください。

パラメーター:

引数 解説
a   array_like   ここに渡した配列の要素を合計します。
axis*      None or int
or tuple of ints  
次元軸を指定します。デフォルト値はNoneです。複数の次元軸の指定も可能です。
dtype*  dtype   戻り値の配列のdtypeを指定します。デフォルトでは、第一引数に渡した配列のdtypeを引き継ぎます。
out* ndarray 戻り値の配列で上書きする配列を指定します。戻り値の配列と、上書きする配列のshapeは一致している必要があります。
keepdims*   bool Trueにすると、元の配列の次元数を維持します。
initial* scalar 足し算を行う開始値を指定します。
where* array_like of bool 足し算に含める要素を、要素がブール値の配列で指定します。
* はオプション引数であることを示します。

戻り値: 

指定の次元軸ごとの合計値を格納した配列
第一引数に渡した配列のshapeから指定したaxisを除いたshapeを持つndarrayになります。axis=None(デフォルト値)の場合は、スカラーが返されます。

一緒に確認したい関数:

  • cumsum: 配列の要素の累積合計を取得
  • mean: 配列の要素の算術平均を取得
  • average: 配列の要素の加重平均を取得
  • trapz: 配列の値を台形公式に統合
ndarray.sum

書き方:

ndarray.sum(axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True)

※コードが見切れています。お手数ですが右にスライドしてご確認ください。

Note

np.sumは整数(int型)を扱う場合はモジュラー計算であり、エラーの心配はありません。

ただし、浮動小数点数(float型)を扱う場合は、1つ1つの数値を個々に足し合わせるというステップを経るため、通常はそのような問題が起きないように対処されているとしても、1つ1つの足し算を行う度に丸めの問題が起きる可能性があります。そのため計算精度については以下の点を理解しておくと良いでしょう。

  • 大量のデータを扱う場合、低精度浮動小数点数(float32など)は大きな問題になりうる。そのような場合はfloat64を使う。
  • axisを指定しない場合が最も計算が精確。
  • axisを指定する場合は、計算精度は、どの次元軸の合計を求めるかに依存する。また他のオプション引数の設定にも依存する。
  • Pythonのmath.fsum関数はnp.sumより低速だが精度が高い。

なお、np.sumに空の配列を渡すと、戻り値は0になります。

In [1]:
import numpy as np
np.sum([])
Out[1]:
0.0

2. サンプルコード

それでは、軸の指定の仕方でどう計算結果が異なるかを、実際のコードを見ながら把握していきましょう。

1次元配列の場合

np.sum()は、引数に渡した配列の要素の合計を戻します。以下の1次元配列a を例にして見ていきましょう。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(0, 11, (5, ))
a
Out[1]:
array([3, 3, 6, 3, 5])

この1次元配列をnp.sum()に渡すと要素の合計値を返します。

In [2]:
# 合計値を取得
np.sum(a)
Out[2]:
20

メソッドも同様です。メソッドの場合は、対象となる配列は引数に渡すのではなく前に書きます。

In [3]:
# ndarray.sum()メソッドも同様
a.sum()
Out[3]:
20

多次元配列の場合

多次元配列の場合もデフォルトでは全要素の合計値を返します。以下の2次元配列を例に見てみましょう。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(0, 31, (3,  5))
a
Out[1]:
array([[27, 22, 17, 25,  9],
       [23, 12,  2,  9,  7],
       [19, 10, 21, 14,  5]])

np.sum()関数も、ndarray.sum()メソッドもともに全要素の合計を返します。

In [2]:
# 合計値を取得
np.sum(a)
Out[2]:
222
In [3]:
# ndarray.sum()メソッドも同様
a.sum()
Out[3]:
222

次元軸の指定

オプション引数 axis で合計値を求める次元軸を指定することができます。

以下は1次元軸(横軸)を指定しています。

In [4]:
# 1次元軸(横軸)を指定
np.sum(a, axis=-1)
Out[4]:
array([100,  53,  69])
In [5]:
# メソッド
a.sum(axis=-1)
Out[5]:
array([100,  53,  69])

以下は2次元軸(縦軸)を指定しています。

In [6]:
# 2次元軸(縦軸)を指定
np.sum(a, axis=0)
Out[6]:
array([69, 44, 40, 48, 21])
In [7]:
# メソッド
a.sum(axis=0)
Out[7]:
array([69, 44, 40, 48, 21])

要素の型(dtype)を指定

上のNoteで述べた通り、浮動小数点数(float型)の計算では、倍精度浮動小数点数(float64)が最も精度が高くなります。元の配列のデータ型が、低精度浮動小数点数(float32)以下の場合は、dtypeでfloat64を指定すると良いでしょう。

以下のコードをご確認ください。なお以降はメソッドのndarray.sum()のサンプルコードは割愛します。書き方は全く同じです。

In [1]:
import numpy as np
a = np.linspace(-10, 10, 100000, dtype=np.float32)
In [2]:
# float32型の計算は精度が低い
np.sum(a)
Out[2]:
0.017578125
In [3]:
# float64型は精度が高い
np.sum(a, dtype=np.float64)
Out[3]:
0.0

次元数を維持(keepdims)

np.sum()の引数に多次元配列を渡して、axis を指定した場合、合計値の配列の次元数は-1になります。この時、オプション引数で keepdims=True を指定した場合、元の配列の次元数を維持することができます。これを使いこなすことによって、配列のブロードキャストが楽になります。

以下の一連のコードで確認しましょう。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(0, 11, (2, 5))
a
Out[1]:
array([[ 6,  5,  3,  0,  3],
       [ 2,  1,  5,  8, 10]])
In [2]:
# 次元数を維持
np.sum(a, axis=-1, keepdims=True)
Out[2]:
array([[17],
       [26]])
In [3]:
np.sum(a, axis=0, keepdims=True)
Out[3]:
array([[ 8,  6,  8,  8, 13]])

足し算の開始値(initial)を指定

オプション引数 initial では足し算の開始値を指定することができます。以下の一連のコードをご覧ください。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(0, 11, (5, ))
a
Out[1]:
array([9, 5, 9, 3, 9])
In [2]:
# 足し算の開始値を指定
np.sum(a, initial=100)
Out[2]:
135

特定の行や列のみの合計を求める(where)

オプション引数whereにブール値の配列や、配列のようなオブジェクト(リストやタプル)を渡すと、合計の対象となる行や列、要素を指定することができます。

これについては、ブロードキャストのルールを理解しておくとわかりやすいので、『覚えておくべきNumPy配列のブロードキャストのルール』を確認しておきましょう。

それでは以下の配列を例に見てみましょう。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(0, 11, (3, 5))
a
Out[1]:
array([[ 2,  2,  0,  6,  8],
       [ 3, 10,  5,  6,  0],
       [ 5,  5,  7,  8, 10]])

この配列の全要素の合計値は以下の通りです。

In [2]:
# 全要素の合計
np.sum(a)
Out[2]:
77

以下のコードでは、オプション引数whereを使って、1行目と3行目の要素の合計を産出しています。

In [3]:
# 1行目と3行目の要素のみ足し算
np.sum(a, where=[[True], [False], [True]])
Out[3]:
53

以下のコードでは、3列目の要素の合計値のみを算出しています。

In [4]:
# 3列目の要素のみ足し算
np.sum(a, where=[0, 0, 1, 0, 0 ])
Out[4]:
12

3. まとめ

以上がnumpy.sumの使い方です。以下の関数も併せて確認しておくと良いでしょう。

  • cumsum: 配列の要素の累積合計を取得
  • mean: 配列の要素の算術平均を取得
  • average: 配列の要素の加重平均を取得



よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる