这里有一个向量化的方法,利用一些缩放技巧和卷积来找到所需的模式 -
最初的回答:
a = df['Event']
id_ar = (a=='ABD') + 2*(a=='B') + 3*(a=='CDE')
mask = id_ar>0
df1 = df[mask]
df1['Pattern'] = (np.convolve(id_ar[mask],[9,1],'same')==28).astype(int)
out = df1.groupby(['Id'])['Pattern'].sum()
那个`卷积(convolution)`部分可能有些棘手。这里的想法是使用值为`1`、`2`和`3`的`id_ar`对应于字符串`'ABD'`、`'B'`和`'CDE'`。我们要寻找的是跟随着`1`之后出现的`3`,所以使用核`[9,1]`进行卷积将导致具有`'ABD'`和然后是`'CDE'`的窗口的卷积总和为`1*1 + 3*9 = 28`。因此,我们寻找匹配的卷积总和为`28`。对于跟随着`'ABD'`、`'B'`和`'CDE'`的情况,卷积总和将不同,因此将被过滤掉。
样例运行 -
1) 输入数据框:
In [377]: df
Out[377]:
Id Event SeqNo
0 1 A 1
1 1 B 2
2 1 C 3
3 1 ABD 4
4 1 B 5
5 1 C 6
6 1 A 7
7 1 CDE 8
8 1 D 9
9 1 B 10
10 1 ABD 11
11 1 D 12
12 1 B 13
13 2 A 1
14 2 B 2
15 2 C 3
16 2 ABD 4
17 2 A 5
18 2 C 6
19 2 A 7
20 2 CDE 8
21 2 D 9
22 2 B 10
23 2 ABD 11
24 2 D 12
25 2 B 13
26 2 CDE 14
27 2 A 15
2) 中间过滤输出(查看
Pattern
列是否包含所需模式):
In [380]: df1
Out[380]:
Id Event SeqNo Pattern
1 1 B 2 0
3 1 ABD 4 0
4 1 B 5 0
7 1 CDE 8 0
9 1 B 10 0
10 1 ABD 11 0
12 1 B 13 0
14 2 B 2 0
16 2 ABD 4 0
20 2 CDE 8 1
22 2 B 10 0
23 2 ABD 11 0
25 2 B 13 0
26 2 CDE 14 0
最终输出:
3)最终结果:
In [381]: out
Out[381]:
Id
1 0
2 1
Name: Pattern, dtype: int64