回答編集履歴

3

追記

2020/03/27 02:35

投稿

kirara0048
kirara0048

スコア1399

test CHANGED
@@ -54,7 +54,9 @@
54
54
 
55
55
  ```python
56
56
 
57
- s = pd.Series([10, 10, 10, 12, 12, 12, 13, 13, 13, 1, 10, 12, 13, 1, 10, 11, 1, 13, 12])
57
+ s = pd.Series([10, 10, 10, 12, 13, 13, 0, 0, 10, 12, 13, 10, 12, 10, 12, 13, 13])
58
+
59
+ # [10, 10, 10, 12, 13, 13, 10, 12, 13, , 10, 12, 13, 13]
58
60
 
59
61
  v = np.array([10, 12, 13])
60
62
 
@@ -72,20 +74,184 @@
72
74
 
73
75
  # 3 12 1
74
76
 
75
- # 4 12 1
76
-
77
- # 5 12 1
78
-
79
- # 6 13 1
80
-
81
- # 7 13 1
82
-
83
- # 8 13 1
84
-
85
- # 9 10 2
86
-
87
- # 10 12 2
88
-
89
- # 11 13 2
90
-
91
- ```
77
+ # 4 13 1
78
+
79
+ # 5 13 1
80
+
81
+ # 6 10 2
82
+
83
+ # 7 12 2
84
+
85
+ # 8 13 2
86
+
87
+ # 9 10 3
88
+
89
+ # 10 12 3
90
+
91
+ # 11 13 3
92
+
93
+ # 12 13 3
94
+
95
+ ```
96
+
97
+
98
+
99
+ ## 挙動の解説
100
+
101
+
102
+
103
+ ### 1. 同じ値が連続する部分の除外
104
+
105
+
106
+
107
+ 「`10,12,13`はどれくらい連続しているか分からない」ということなので、同じ数が連続する部分をひとまとめにします。これは、インデックスを一つずらした配列と比較することで取得できます。
108
+
109
+
110
+
111
+ ```python
112
+
113
+ cut_index, = np.r_[True, a[1:] != a[:-1], True].nonzero()
114
+
115
+ short_a = a[cut_index[:-1]]
116
+
117
+
118
+
119
+ """
120
+
121
+ a : [10, 10, 10, 12, 13, 13, 0, 0, 10, 12, 13, 10, 12, 10, 12, 13, 13]
122
+
123
+
124
+
125
+ a[1:] : 10 [10, 10, 12, 13, 13, 0, 0, 10, 12, 13, 10, 12, 10, 12, 13, 13]
126
+
127
+ a[:-1] : [10, 10, 10, 12, 13, 13, 0, 0, 10, 12, 13, 10, 12, 10, 12, 13] 13
128
+
129
+ a[1:] != a[:-1] : [ F, F, T, T, F, T, F, T, T, T, T, T, T, T, T, F]
130
+
131
+ (concatenate) : [ T, F, F, T, T, F, T, F, T, T, T, T, T, T, T, T, F, T]
132
+
133
+
134
+
135
+ cut_index : [ 0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 17]
136
+
137
+ short_a : [10, 12, 13, 0, 10, 12, 13, 10, 12, 10, 12, 13, ]
138
+
139
+ """
140
+
141
+ ```
142
+
143
+
144
+
145
+ ### 2. 一致箇所の検索
146
+
147
+
148
+
149
+ 前節で作成した配列`short_a`から、`10,12,13`のまとまりを探します。
150
+
151
+ そのためにまず、`short_a`を3つずつ区切るためのインデックスを作成します。
152
+
153
+
154
+
155
+ ```python
156
+
157
+ slide_index = np.arange(short_a.size-v_size+1)[:, None] + np.arange(v_size)
158
+
159
+ print(slide_index)
160
+
161
+ # [[ 0 1 2]
162
+
163
+ # [ 1 2 3]
164
+
165
+ # [ 2 3 4]
166
+
167
+ # ...
168
+
169
+ # [ 7 8 9]
170
+
171
+ # [ 8 9 10]
172
+
173
+ # [ 9 10 11]]
174
+
175
+ ```
176
+
177
+
178
+
179
+ `v`と比較することで、`10,12,13`と一致する箇所を探します。
180
+
181
+
182
+
183
+ ```python
184
+
185
+ match = (short_a[slide_index] == v).all(1)
186
+
187
+
188
+
189
+ """
190
+
191
+ slide_a : [[10, 12, 13], [12, 13, 0], [13, 0, 10], [ 0, 10, 12], [10, 12, 13], ...]
192
+
193
+ v : [[10, 12, 13], [ > ], [ > ], [ > ], [ > ], ...]
194
+
195
+ match : [ True, False, False, False, True, ...]
196
+
197
+ """
198
+
199
+ ```
200
+
201
+
202
+
203
+ `match`で得られた`True`は、`10,12,13`の`10`の位置のみなので、`np.convolve()`を利用して`10,12,13`の位置が`True`になるようにします。
204
+
205
+
206
+
207
+ ```python
208
+
209
+ all_match = np.convolve(match, np.ones(v_size, dtype=int))
210
+
211
+
212
+
213
+ """
214
+
215
+ short_a : [10, 12, 13, 0, 10, 12, 13, 10, 12, 10, 12, 13]
216
+
217
+ match : [ T, F, F, F, T, F, F, F, F, T]
218
+
219
+ all_match : [ 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1]
220
+
221
+ """
222
+
223
+ ```
224
+
225
+
226
+
227
+ ### 3. 一致箇所の拡大復元
228
+
229
+
230
+
231
+ 前節で求めた`all_match`は、`10,10,10`のように同じ値が連続する部分がまとまった配列に対する位置なので、`np.repeat()`を用いて1.の逆を行います。
232
+
233
+
234
+
235
+ ```python
236
+
237
+ index, = np.repeat(all_match, np.ediff1d(cut_index)).nonzero()
238
+
239
+
240
+
241
+ """
242
+
243
+ a : [10, 10, 10, 12, 13, 13, 0, 0, 10, 12, 13, 10, 12, 10, 12, 13, 13]
244
+
245
+ cut_index : [ 0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 17]
246
+
247
+
248
+
249
+ all_match : [ 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, ]
250
+
251
+ (repeat) : [ 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1]
252
+
253
+ index : [ 0, 1, 2, 3, 4, 5, 8, 9, 10, 13, 14, 15, 16]
254
+
255
+ """
256
+
257
+ ```

2

微修正

2020/03/27 02:35

投稿

kirara0048
kirara0048

スコア1399

test CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
 
40
40
 
41
- return pd.DataFrame({'value': result_array, 'index': result_index})
41
+ return pd.DataFrame({'num': result_array, 'id': result_index})
42
42
 
43
43
  ```
44
44
 
@@ -62,30 +62,30 @@
62
62
 
63
63
  function(s.to_numpy(), v)
64
64
 
65
- # value index
65
+ # num id
66
66
 
67
- # 0 10 1
67
+ # 0 10 1
68
68
 
69
- # 1 10 1
69
+ # 1 10 1
70
70
 
71
- # 2 10 1
71
+ # 2 10 1
72
72
 
73
- # 3 12 1
73
+ # 3 12 1
74
74
 
75
- # 4 12 1
75
+ # 4 12 1
76
76
 
77
- # 5 12 1
77
+ # 5 12 1
78
78
 
79
- # 6 13 1
79
+ # 6 13 1
80
80
 
81
- # 7 13 1
81
+ # 7 13 1
82
82
 
83
- # 8 13 1
83
+ # 8 13 1
84
84
 
85
- # 9 10 2
85
+ # 9 10 2
86
86
 
87
- # 10 12 2
87
+ # 10 12 2
88
88
 
89
- # 11 13 2
89
+ # 11 13 2
90
90
 
91
91
  ```

1

微修正

2020/03/19 05:08

投稿

kirara0048
kirara0048

スコア1399

test CHANGED
@@ -22,13 +22,13 @@
22
22
 
23
23
  short_a = a[cut_index[:-1]]
24
24
 
25
- slide_index = np.arange(short_a.size-v.size+1)[:, None] + np.arange(v.size)
25
+ slide_index = np.arange(short_a.size-v_size+1)[:, None] + np.arange(v_size)
26
26
 
27
27
  match = (short_a[slide_index] == v).all(1)
28
28
 
29
29
  all_match = np.convolve(match, np.ones(v_size, dtype=int))
30
30
 
31
- index = np.repeat(all_match, np.ediff1d(cut_index)).nonzero()[0]
31
+ index, = np.repeat(all_match, np.ediff1d(cut_index)).nonzero()
32
32
 
33
33
 
34
34