teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

解説を追加

2018/05/28 00:18

投稿

magichan
magichan

スコア15898

answer CHANGED
@@ -11,4 +11,81 @@
11
11
  data = pd.read_csv('in.csv')
12
12
  data['rms'] = data.iloc[:,0].rolling(window=window_size, min_periods=1, center=True).apply(rms)
13
13
  data.to_csv('out.csv', index=None)
14
- ```
14
+ ```
15
+
16
+ ---
17
+
18
+ **【補足】**
19
+
20
+ 簡単に説明します。
21
+
22
+ まず [1,2,3,4,5,6,7,8,9] といった1次元配列(pandas.Series)があった場合、RMSは
23
+
24
+ ```Python
25
+ import pandas as pd
26
+ import numpy as np
27
+
28
+ row_data = pd.Series([1,2,3,4,5,6,7,8,9])
29
+ res = np.sqrt((row_data ** 2).sum() / row_data.size)
30
+ print(res)
31
+ #5.627314338711377
32
+ ```
33
+
34
+ で求めることができますので、このRMSを求める式を ``lambda``で関数化しておいて
35
+
36
+ ```Python
37
+ import pandas as pd
38
+ import numpy as np
39
+
40
+ row_data = pd.Series([1,2,3,4,5,6,7,8,9])
41
+ rms = lambda d: np.sqrt((d ** 2).sum() / d.size)
42
+
43
+ res = rms(row_data)
44
+ print(res)
45
+ #5.627314338711377
46
+ ```
47
+ となります。
48
+
49
+ 次に、今回の質問のコードの場合、列全体のRMSを求めるのではなく一定区間のRMSをずらしながら求めることが要求されておりますので、この部分は``Series.rolling()`` を使用することになります。
50
+ ``Series.rolling()`` を簡単なサンプルで説明すると、例えば [1,2,3,4,5,6,7,8,9] といった1次元配列に対して``rolling().sum()`` を適用するとにより
51
+ ```Python
52
+ row_data = pd.Series([1,2,3,4,5,6,7,8,9])
53
+ res = row_data.rolling(window=3).sum()
54
+ print(res)
55
+ #0 NaN
56
+ #1 NaN
57
+ #2 6.0
58
+ #3 9.0
59
+ #4 12.0
60
+ #5 15.0
61
+ #6 18.0
62
+ #7 21.0
63
+ #8 24.0
64
+ #dtype: float64
65
+ ```
66
+
67
+ のように、一定区間(今回はwindow=3で指定した区間)毎の合計を求めることができます。
68
+ 今回の場合は一定区間毎の合計では無く、自作した関数(rms)を適用したいので、``Series.rolling().apply()``を使用して
69
+
70
+ ```Python
71
+ row_data = pd.Series([1,2,3,4,5,6,7,8,9])
72
+
73
+ rms = lambda d: np.sqrt((d ** 2).sum() / d.size)
74
+ res = row_data.rolling(window=3).apply(rms)
75
+ print(res)
76
+ #0 NaN
77
+ #1 NaN
78
+ #2 2.160247
79
+ #3 3.109126
80
+ #4 4.082483
81
+ #5 5.066228
82
+ #6 6.055301
83
+ #7 7.047458
84
+ #8 8.041559
85
+ #dtype: float64
86
+ ```
87
+ となります。
88
+
89
+ 最後に、rollingのパラメータですが、上記の例では ``index=0,1`` の箇所の結果が``NaN``になっております。これはこの部分を計算するための入力データの数が区間数(Window=3)を満たしておらず計算が出来ないためです。そこで``min_periods=1`` をパラメータで渡し、入力データが最低でも1つあれば計算を行うよう指定しております。さらに上記の例では 入力データ``index=0,1,2``の結果が``index=2``に入っております。そこで``center=True``を渡す事により index=0,1,2の結果が index=1 に出力されるようにしております。
90
+
91
+ 以上です。