在pandas中为groupby创建序列模式

yftpprvb  于 2023-10-14  发布在  其他
关注(0)|答案(2)|浏览(84)

我有一个三列ID的数据集,'sort_seq and level . basically i want to identify id wise level sequence sort by sort_seq. please suggest any optimal code other then for loop',因为它需要更长的时间与字典和追加列表。

输入数据集

import pandas as pd
import numpy as np
data = {'id': [1, 1, 1, 1,2, 2, 3, 3, 3, 3, 4, 5, 5, 6],
        'sort_seq': [89, 24, 56,  8,  5, 64, 93, 88, 61, 31, 50, 75,  1, 81],
        'level':['a', 'a',  'b', 'c', 'x', 'x', 'g', 'a', 'b', 'b', 'b', 'c', 'c','b']}
df = pd.DataFrame(data)

预期产出

尝试代码

collect = []
for ij in df.id.unique():
  idict = {}
  x =  df[df['id'] == ij]
  x = x.sort_values(by='sort_seq',ascending=True)
  x = x.reset_index()
  idict[ij] =  x['level'].tolist()
  collect.append(idict)
collect
dm7nw8vv

dm7nw8vv1#

首先按DataFrame.sort_values对两列进行排序,然后按level中的连续值进行分组,计数器按Series.value_counts,按level的值连接计数数,因此可能按join进行聚合:

np.random.seed(123)
    
data = {'id': [1, 1, 1, 1,2, 2, 3, 3, 3, 3, 4, 5, 5, 6],
        'sort_seq': np.random.randint(0, 100, size=14),
        'level':['a', 'a',  'b', 'c', 'x', 'x', 'g', 'a', 'b', 'b', 'b', 'c', 'c','b']}
df = pd.DataFrame(data)
df1 = df.sort_values(['id','sort_seq'])

df1 = (df1.groupby(['id', df1['level'].ne(df1['level'].shift()).cumsum()])['level']
          .value_counts()
          .droplevel(1)
          .rename('col')
          .reset_index()
          .assign(level=lambda x: x['col'].astype(str) + x['level'])
          .groupby('id')['level'].agg(','.join)
          .reset_index(name='PATTERN')
           )
print(df1)

   id      PATTERN
0   1     1c,2a,1b
1   2           2x
2   3  1b,1g,1b,1a
3   4           1b
4   5           2c
5   6           1b

或者在理解中使用itertools.groupbyCounter

import itertools
from collections import Counter

f = lambda x: ','.join(f'{b}{a}' 
                        for _, g in itertools.groupby(x) 
                        for a, b in Counter(g).items())
df1 = (df.sort_values(['id','sort_seq'])
         .groupby('id')['level']
         .agg(f)
         .reset_index(name='PATTERN'))
           
print(df1)
   id      PATTERN
0   1     1c,2a,1b
1   2           2x
2   3  1b,1g,1b,1a
3   4           1b
4   5           2c
5   6           1b
tez616oj

tez616oj2#

验证码

grp = df.sort_values(['id', 'sort_seq'])['level'].ne(df.sort_values(['id', 'sort_seq']).groupby('id')['level'].shift()).cumsum()
df.groupby(['id', grp])['level'].agg(['count', 'first'])\
  .assign(pattern=lambda x: x['count'].astype('str') + x['first'])\
  .groupby(level=0)['pattern'].agg(','.join).reset_index()

产出:

id  pattern
0   1   1c,1a,1b,1a
1   2   2x
2   3   2b,1a,1g
3   4   1b
4   5   2c
5   6   1b

与您想要的输出不同,您示例中的输出应为id 32b

中级

组:

df
    id  sort_seq    level               grp
0   1   89          a                   4
1   1   24          a                   2
2   1   56          b                   3
3   1   8           c                   1
4   2   5           x                   5
5   2   64          x                   5
6   3   93          g                   8
7   3   88          a                   7
8   3   61          b                   6
9   3   31          b                   6
10  4   50          b                   9
11  5   75          c                   10
12  5   1           c                   10
13  6   81          b                   11

相关问题