NumPyで累積和・累積積(np.cumsum, np.cumprod)

Posted: | Tags: Python, NumPy

NumPyで累積和や累積積を生成するには、numpy.cumsum(), numpy.cumprod()関数、または、numpy.ndarraycumsum(), cumprod()メソッドを使う。

ここでは、以下の内容について説明する。

  • 累積和: numpy.cumsum()
  • 累積積: numpy.cumprod()

累積和・累積積はPythonの標準ライブラリitertoolsやpandasの関数・メソッドでも生成可能。itertoolsでは任意の関数を累積的に適用できる。

累積和: numpy.cumsum()

基本的な使い方

以下の一次元の配列numpy.ndarrayを例とする。

import numpy as np

print(np.__version__)
# 1.19.0

a_1d = np.array([1, 2, 3, 4, 5, 6])
print(a_1d)
# [1 2 3 4 5 6]

np.cumsum()で累積和を取得できる。返り値はnumpy.ndarrayで、引数dtypeでそのデータ型を指定可能。

print(np.cumsum(a_1d))
# [ 1  3  6 10 15 21]

print(np.cumsum(a_1d, dtype=float))
# [ 1.  3.  6. 10. 15. 21.]

numpy.ndarrayのメソッドとしてもcumsum()が提供されている。dtypeや後述のaxisなど、引数はnp.cumsum()関数と同じ。

print(a_1d.cumsum())
# [ 1  3  6 10 15 21]

print(a_1d.cumsum(dtype=float))
# [ 1.  3.  6. 10. 15. 21.]

np.cumsum()の第一引数には、numpy.ndarrayだけでなく、リストなどのいわゆるarray-likeオブジェクトを指定可能。結果はnumpy.ndarrayなので注意。

l = [1, 2, 3, 4, 5, 6]

print(np.cumsum(l))
# [ 1  3  6 10 15 21]

print(type(np.cumsum(l)))
# <class 'numpy.ndarray'>

numpy.ndarrayをリストに変換したい場合は以下の記事を参照。

多次元配列の場合

以下の二次元の配列numpy.ndarrayを例とする。

a_2d = a_1d.reshape(2, 3)
print(a_2d)
# [[1 2 3]
#  [4 5 6]]

多次元配列に対しては、デフォルトでは、一次元に平坦化した累積和が生成される。

print(np.cumsum(a_2d))
# [ 1  3  6 10 15 21]

引数axisを指定すると軸(次元)ごとに累積和を算出できる。二次元配列の場合、axis=0で列ごと、axis=1で行ごととなる。

print(np.cumsum(a_2d, axis=0))
# [[1 2 3]
#  [5 7 9]]

print(np.cumsum(a_2d, axis=1))
# [[ 1  3  6]
#  [ 4  9 15]]

numpy.ndarraycumsum()メソッドでも同様。

print(a_2d.cumsum())
# [ 1  3  6 10 15 21]

print(a_2d.cumsum(axis=0))
# [[1 2 3]
#  [5 7 9]]

print(a_2d.cumsum(axis=1))
# [[ 1  3  6]
#  [ 4  9 15]]

np.cumsum()の第一引数にリストのリストを指定した場合も同様。

l_2d = [[1, 2, 3], [4, 5, 6]]

print(np.cumsum(l_2d))
# [ 1  3  6 10 15 21]

print(np.cumsum(l_2d, axis=0))
# [[1 2 3]
#  [5 7 9]]

print(np.cumsum(l_2d, axis=1))
# [[ 1  3  6]
#  [ 4  9 15]]

なお、内側のリストの要素数が異なる場合は、多次元配列ではなくそれぞれのリストを要素とした配列として扱われるため、所望の結果にはならない。要注意。

l_2d_error = [[1, 2, 3], [4, 5]]

print(np.cumsum(l_2d_error))
# [list([1, 2, 3]) list([1, 2, 3, 4, 5])]

累積積: numpy.cumprod()

累積積はnumpy.cumprod()で生成できる。使い方は上述のnumpy.cumsum()と同じ。こちらもnumpy.ndarrayのメソッドとしても提供されている。

print(np.cumprod(a_1d))
# [  1   2   6  24 120 720]

print(np.cumprod(a_1d, dtype=float))
# [  1.   2.   6.  24. 120. 720.]

print(a_1d.cumprod())
# [  1   2   6  24 120 720]

print(a_1d.cumprod(dtype=float))
# [  1.   2.   6.  24. 120. 720.]

多次元配列でも同様。

print(np.cumprod(a_2d))
# [  1   2   6  24 120 720]

print(np.cumprod(a_2d, axis=0))
# [[ 1  2  3]
#  [ 4 10 18]]

print(np.cumprod(a_2d, axis=1))
# [[  1   2   6]
#  [  4  20 120]]

print(a_2d.cumprod())
# [  1   2   6  24 120 720]

print(a_2d.cumprod(axis=0))
# [[ 1  2  3]
#  [ 4 10 18]]

print(a_2d.cumprod(axis=1))
# [[  1   2   6]
#  [  4  20 120]]

numpy.cumsum()と同じくnumpy.cumprod()の引数にもリストなどのarray-likeオブジェクトを指定可能。

print(np.cumprod(l))
# [  1   2   6  24 120 720]

print(np.cumprod(l_2d))
# [  1   2   6  24 120 720]

print(np.cumprod(l_2d, axis=0))
# [[ 1  2  3]
#  [ 4 10 18]]

print(np.cumprod(l_2d, axis=1))
# [[  1   2   6]
#  [  4  20 120]]

関連カテゴリー

関連記事