NumPy:累積和と累積積を求める(cumsum, cumprod)
累積和と累積積は、配列の先頭から順番に値を足したり掛けたりしていく計算です。NumPy では cumsum と cumprod で簡単に求められます。
累積和: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 として扱います。