NumPy:累積和と累積積を求める(cumsum, cumprod)

累積和と累積積は、配列の先頭から順番に値を足したり掛けたりしていく計算です。NumPy では cumsumcumprod で簡単に求められます。

累積和:cumsum

np.cumsum() は、先頭から順に値を足していった結果を返します。

import numpy as np

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

result = np.cumsum(data)
print(result)  # [ 1  3  6 10 15]

計算の流れは以下のようになっています。

# 1
# 1 + 2 = 3
# 1 + 2 + 3 = 6
# 1 + 2 + 3 + 4 = 10
# 1 + 2 + 3 + 4 + 5 = 15

累積積:cumprod

np.cumprod() は、先頭から順に値を掛けていった結果を返します。

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

result = np.cumprod(data)
print(result)  # [  1   2   6  24 120]

計算の流れは以下の通りです。

# 1
# 1 * 2 = 2
# 1 * 2 * 3 = 6
# 1 * 2 * 3 * 4 = 24
# 1 * 2 * 3 * 4 * 5 = 120

階乗の計算にも使えます。1, 2, 3, 4, 5 の累積積の最後の値は 5! = 120 です。

多次元配列での使用

axis を指定すると、特定の軸方向に累積計算ができます。

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

# 行方向(axis=0):縦に累積
print(np.cumsum(a, axis=0))
# [[1 2 3]
#  [5 7 9]]

# 列方向(axis=1):横に累積
print(np.cumsum(a, axis=1))
# [[ 1  3  6]
#  [ 4  9 15]]

axis を指定しないと、配列を平坦化してから累積計算します。

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

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

実用例:ランニングトータル

売上データなどで、月ごとの累計を計算するのに便利です。

monthly_sales = np.array([100, 150, 120, 200, 180])

cumulative_sales = np.cumsum(monthly_sales)
print(cumulative_sales)  # [100 250 370 570 750]

グラフにすると、累積の推移がわかりやすくなります。

実用例:複利計算

累積積は複利計算に使えます。毎年の成長率を掛け合わせていくことで、元本がどう増えていくかを計算できます。

# 年ごとの成長率(1.05 = 5%成長)
growth_rates = np.array([1.05, 1.03, 1.08, 1.02, 1.06])

# 累積成長率
cumulative_growth = np.cumprod(growth_rates)
print(cumulative_growth)
# [1.05   1.0815 1.16802 1.19138... 1.26286...]

# 元本100万円の場合
initial = 1000000
values = initial * cumulative_growth
print(values.astype(int))  # [1050000 1081500 1168020 1191380 1262863]

nanを含む場合

欠損値を含むデータには np.nancumsum() を使います。nan を 0 として扱います。

data = np.array([1, 2, np.nan, 4, 5])

print(np.cumsum(data))     # [ 1.  3. nan nan nan]
print(np.nancumsum(data))  # [ 1.  3.  3.  7. 12.]

nancumprod もあり、nan を 1 として扱います。