关于pandas:从列表到列表的一个列表作为列表的子列表

a list as a sublist of a list from group into list

我有一个数据框,其中有2列,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    a  b
0   1  2
1   1  1
2   1  1
3   1  2
4   1  1
5   2  0
6   2  1
7   2  1
8   2  2
9   2  2
10  2  1
11  2  1
12  2  2

是否有直接方法可以制作如下第三列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    a  b  c
0   1  2  0
1   1  1  1
2   1  1  0
3   1  2  1
4   1  1  0
5   2  0  0
6   2  1  1
7   2  1  0
8   2  2  1
9   2  2  0
10  2  1  0
11  2  1  0
12  2  2  0

其中目标[1, 2]df.groupby('a').b.apply(list)的子列表,找到每个组中首先适合目标的2行。

df.groupby('a').b.apply(list)给出

1
2
1             [2, 1, 1, 2, 1]
2    [0, 1, 1, 2, 2, 1, 1, 2]

[1,2][2, 1, 1, 2, 1][0, 1, 1, 2, 2, 1, 1, 2]

的子列表

到目前为止,我有一个功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def is_sub_with_gap(sub, lst):
    '''
    check if sub is a sublist of lst
    '''
    ln, j = len(sub), 0
    ans = []
    for i, ele in enumerate(lst):
        if ele == sub[j]:
            j += 1
            ans.append(i)
           
        if j == ln:
            return True, ans
    return False, []

测试功能

1
2
In [55]: is_sub_with_gap([1,2], [2, 1, 1, 2, 1])
Out[55]: (True, [1, 3])


您可以通过在自定义函数中选择组的索引值来更改输出,通过Series.explode对其进行展平,然后通过Index.isin

测试索引值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
L = [1, 2]

def is_sub_with_gap(sub, lst):
    '''
    check of sub is a sublist of lst
    '''
    ln, j = len(sub), 0
    ans = []
    for i, ele in enumerate(lst):
        if ele == sub[j]:
            j += 1
            ans.append(i)
           
        if j == ln:
            return lst.index[ans]
    return []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
idx = df.groupby('a').b.apply(lambda x: is_sub_with_gap(L, x)).explode()

df['c'] = df.index.isin(idx).view('i1')
print (df)
    a  b  c
0   1  2  0
1   1  1  1
2   1  1  0
3   1  2  1
4   1  1  0
5   2  0  0
6   2  1  1
7   2  1  0
8   2  2  1
9   2  2  0
10  2  1  0
11  2  1  0
12  2  2  0