回答編集履歴
1
解説を追加
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
|
+
以上です。
|