【NumPy】累積和を計算する方法(np.cumsum)と累積積を計算する方法(np.cumprod)[Python]

  • URLをコピーしました!
目次

NumPy

前回、PythonのNumPyでbool値のリスト内のTrueの数を数える方法を紹介しました。

今回はNumPyで累積和を計算する方法(np.cumsum)と累積積を計算する方法を紹介します。

累積和とは、例えば「1, 2, 3, 4, 5」というリストがあった場合、まず最初は「1」、次にリストの最初の二つの数字を取り「1+2=3」と足し算をします。

そしてその「3」とリストの3番目の「3」を足し算し「6」、その「6」とリストの4番目の「4」を足して「10」、その「10」とリストの最後の「5」を足して「15」というように次々とリストの要素を足し算していくことを指します。

つまり「1, 2, 3, 4, 5」の累積和は「1, 3, 6, 10, 15」となります。

累積積は累積和の掛け算バージョンで、「1, 2, 3, 4, 5」のリストの場合、「1, 2, 6, 24, 120」となります。

それでは始めていきましょう。

累積和を計算する方法:np.cumsum

リストの累積和を計算するには「np.cumsum(リスト)」を用います。

import numpy as np

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

print(np.cumsum(a))

実行結果
[ 1  3  6 10 15]

2次元以上のリストの場合、「axis」のオプション引数で累積和を計算する軸方向を指定できます。

指定しない場合は全てのリストの累積和が計算されます。

import numpy as np

b = [[1, 2, 3, 4, 5],
     [6, 7, 8, 9, 10]]

print(np.cumsum(b))
print(np.cumsum(b, axis=0))
print(np.cumsum(b, axis=1))

実行結果
[ 1  3  6 10 15 21 28 36 45 55]
[[ 1  2  3  4  5]
 [ 7  9 11 13 15]]
[[ 1  3  6 10 15]
 [ 6 13 21 30 40]]

2次元以上の場合、内部のリストの要素の数は同じである必要があります。

異なる場合はエラーとなります。

import numpy as np

c = [[1, 2, 3, 4, 5],
     [6, 7, 8]]

print(np.cumsum(c))
print(np.cumsum(c, axis=0))
print(np.cumsum(c, axis=1))

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[12], line 6
      1 import numpy as np
      3 c = [[1, 2, 3, 4, 5],
      4      [6, 7, 8]]
----> 6 print(np.cumsum(c))
      7 print(np.cumsum(c, axis=0))
      8 print(np.cumsum(c, axis=1))

(中略)

ValueError: setting an array element with a sequence. The requested 
array has an inhomogeneous shape after 1 dimensions. The detected 
shape was (2,) + inhomogeneous part.

累積積を計算する方法:np.cumprod

リストの累積積を計算するには「np.cumpord(リスト)」を用います。

import numpy as np

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

print(np.cumprod(a))

実行結果
[  1   2   6  24 120]

2次元以上のリストの場合、「axis」のオプション引数で累積積を計算する軸方向を指定できます。

指定しない場合は全てのリストの累積積が計算されます。

import numpy as np

b = [[1, 2, 3, 4, 5],
     [6, 7, 8, 9, 10]]

print(np.cumprod(b))
print(np.cumprod(b, axis=0))
print(np.cumprod(b, axis=1))

実行結果
[      1       2       6      24     120     720    5040   40320  
362880 3628800]
[[ 1  2  3  4  5]
 [ 6 14 24 36 50]]
[[    1     2     6    24   120]
 [    6    42   336  3024 30240]]

2次元以上の場合、内部のリストの要素の数は同じである必要があります。

異なる場合はエラーとなります。

import numpy as np

c = [[1, 2, 3, 4, 5],
     [6, 7, 8]]

print(np.cumprod(c))
print(np.cumprod(c, axis=0))
print(np.cumprod(c, axis=1))

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[14], line 6
      1 import numpy as np
      3 c = [[1, 2, 3, 4, 5],
      4      [6, 7, 8]]
----> 6 print(np.cumprod(c))
      7 print(np.cumprod(c, axis=0))
      8 print(np.cumprod(c, axis=1))

(中略)

ValueError: setting an array element with a sequence. The requested 
array has an inhomogeneous shape after 1 dimensions. The detected 
shape was (2,) + inhomogeneous part.

おまけ:累積差、累積商を計算する方法

需要があるのか分かりませんが、累積差と累積商(こんな言葉あるのかな?)を計算する方法も紹介します。

累積差の場合、リストの2つ目以降の要素に「-1」をかけて累積和を計算します。

その際、NumPyのndarrayを連結する「np.concatenate」を使って、最初の要素と2番目以降の要素に-1をかけた要素を連結します。

import numpy as np

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

a_minus = np.concatenate([[a[0]], -1*a[1:]])

print(a_minus)
print(np.cumsum(a_minus))

実行結果
[ 1 -2 -3 -4 -5]
[  1  -1  -4  -8 -13]

累積商も同じ考えで、最初の要素とリストの2番目以降の要素の逆数を連結し、累積積を計算します。

import numpy as np

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

a_divide = np.concatenate([[a[0]], 1/a[1:]])

print(a_divide)
print(np.cumprod(a_divide))

実行結果
[1.         0.5        0.33333333 0.25       0.2       ]
[1.         0.5        0.16666667 0.04166667 0.00833333]

次回はNumPyでndarrayを連結する方法(np.concatenate)を紹介します。

ではでは今回はこんな感じで。

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

コメント

コメントする

目次