統計検定 2級で、産業系の指数の、前期比伸び率、前年同期比伸び率、四半期移動平均を答える問題が出題されます。
python で、指数の時系列データを読み込んで、前期比伸び率、前年同期比伸び率、四半期移動平均 の計算ができるか試してみました。
結果を以下に記載します。
入力データについて
最新結果の概要|全産業活動指数|経済産業省 の、時系列表
> 原指数
の時系列データを計算に用います。
使用するライブラリについて
計算には以下のライブラリを用います。
移動平均
- numpy
- pandas
各月ごとに計算する
ファイルの読み込み
各値の計算をするため、まずファイルを読み込みます。
# データの読み込み
import pandas as pd
df1 = pd.read_table("All-industry-activity-index.tsv")
df1
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
日付 | 原指数 | |
---|---|---|
0 | 2017/03 | 113.6 |
1 | 2017/04 | 101.8 |
2 | 2017/05 | 100.9 |
3 | 2017/06 | 105.3 |
4 | 2017/07 | 105.0 |
5 | 2017/08 | 103.3 |
6 | 2017/09 | 106.5 |
7 | 2017/10 | 105.0 |
8 | 2017/11 | 105.2 |
9 | 2017/12 | 111.2 |
10 | 2018/01 | 101.1 |
11 | 2018/02 | 100.8 |
12 | 2018/03 | 114.9 |
13 | 2018/04 | 103.2 |
14 | 2018/05 | 102.5 |
グラフ描画
原指数のグラフを描画します。
%matplotlib inline
import matplotlib.pyplot as plt
# matplotlib の設定を調整
plt.rcParams['font.family'] = 'IPAPGothic' #全体のフォントを設定
plt.rcParams["figure.figsize"] = [12, 6]
plt.rcParams['font.size'] = 20 #フォントサイズを設定 default : 12
plt.rcParams['xtick.labelsize'] = 15 # 横軸のフォントサイズ
plt.rcParams['ytick.labelsize'] = 15
df1.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x115efec88>
前月比を追加する
diff
で前月との差分、pct_change
で変化率、rolling
で移動平均を計算できます。
df1['前月差分']= df1['原指数'].diff()
df1['変化率']= df1['原指数'].pct_change()
df1['移動平均'] = df1['原指数'].rolling(window=3, center=False).mean()
df1.head()
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
日付 | 原指数 | 前月差分 | 変化率 | 移動平均 | |
---|---|---|---|---|---|
0 | 2017/03 | 113.6 | NaN | NaN | NaN |
1 | 2017/04 | 101.8 | -11.8 | -0.103873 | NaN |
2 | 2017/05 | 100.9 | -0.9 | -0.008841 | 105.433333 |
3 | 2017/06 | 105.3 | 4.4 | 0.043608 | 102.666667 |
4 | 2017/07 | 105.0 | -0.3 | -0.002849 | 103.733333 |
移動平均の 1番目、2番目がNaN
なのは、window指定が 3 のためです。
続いて原指数と、移動平均のグラフを描いてみます。
df1.loc[:,['移動平均','原指数']].plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1161e0ac8>
四半期ごとに計算する
元データは、毎月ごとの時系列データになっています。これを、DatetimeIndex の quarter を使用して四半期ごとに集計します。
四半期ごとにデータをグルーピングする
# データの読み込み
import pandas as pd
df2 = pd.read_table("All-industry-activity-index.tsv")
# 日付 を DatetimeIndex に変換、INDEXとして設定
df2 = df2.set_index(pd.DatetimeIndex(df['日付']))
# DatetimeIndex に四半期ごとにグループ化
df_q = df2.set_index([df2.index.quarter, df2.index.year, df2.index])
df_q.index.names = ['quarter', 'year', 'date']
df_q
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
日付 | 原指数 | |||
---|---|---|---|---|
quarter | year | date | ||
1 | 2017 | 2017-03-01 | 2017/03 | 113.6 |
2 | 2017 | 2017-04-01 | 2017/04 | 101.8 |
2017-05-01 | 2017/05 | 100.9 | ||
2017-06-01 | 2017/06 | 105.3 | ||
3 | 2017 | 2017-07-01 | 2017/07 | 105.0 |
2017-08-01 | 2017/08 | 103.3 | ||
2017-09-01 | 2017/09 | 106.5 | ||
4 | 2017 | 2017-10-01 | 2017/10 | 105.0 |
2017-11-01 | 2017/11 | 105.2 | ||
2017-12-01 | 2017/12 | 111.2 | ||
1 | 2018 | 2018-01-01 | 2018/01 | 101.1 |
2018-02-01 | 2018/02 | 100.8 | ||
2018-03-01 | 2018/03 | 114.9 | ||
2 | 2018 | 2018-04-01 | 2018/04 | 103.2 |
2018-05-01 | 2018/05 | 102.5 |
df_q = df_q.mean(level=['quarter','year'])
df_q['前期比伸び率']= df_q['原指数'].pct_change()
df_q['前年同期比伸び率'] = (df_q['原指数'] - df_q['原指数'].shift(4)) / df_q['原指数']
df_q['四半期移動平均'] = df_q['原指数'].rolling(window=4, center=True).mean()
df_q
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
原指数 | 前期比伸び率 | 四半期移動平均 | 前年同期比伸び率 | ||
---|---|---|---|---|---|
quarter | year | ||||
1 | 2017 | 113.600000 | NaN | NaN | NaN |
2 | 2017 | 102.666667 | -0.096244 | NaN | NaN |
3 | 2017 | 104.933333 | 0.022078 | 107.083333 | NaN |
4 | 2017 | 107.133333 | 0.020966 | 105.083333 | NaN |
1 | 2018 | 105.600000 | -0.014312 | 105.129167 | -0.075758 |
2 | 2018 | 102.850000 | -0.026042 | NaN | 0.001783 |
pandas の rolling だと、偶数の中心化移動平均の計算は実行できないようです。
続いて原指数と、移動平均のグラフを描いてみます。
df_q.loc[:,['四半期移動平均','原指数']].plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1166f8630>
四半期の移動平均は、前後の点が少ないため、あまり算出できていません。
四半期のデータではない場合もmin_periods を指定することで、計算に必要なデータが少ない場合も、移動平均を算出することができます。
参考
以下、参考にした記事になります。
- 移動平均(単純移動平均と中心化移動平均) | 統計学が学べるパソコン教室 KIT
- Pandasによる実践データ分析入門 - Gunosyデータ分析ブログ
- pandas.DataFrame.rolling — pandas 0.22.0 documentation
- pandasで時系列データの曜日や月、四半期、年ごとの合計や平均を算出 | note.nkmk.me
以上です。
コメント