NumPyで累積和・累積積(np.cumsum, np.cumprod)
NumPyで累積和や累積積を生成するには、numpy.cumsum()
, numpy.cumprod()
関数、または、numpy.ndarray
のcumsum()
, cumprod()
メソッドを使う。
- numpy.cumsum — NumPy v1.19 Manual
- numpy.cumprod — NumPy v1.19 Manual
- numpy.ndarray.cumsum — NumPy v1.19 Manual
- numpy.ndarray.cumprod — NumPy v1.19 Manual
ここでは、以下の内容について説明する。
- 累積和:
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.ndarray
のcumsum()
メソッドでも同様。
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]]