如何在组中逐项查找唯一值?

2024-10-01 00:20:02 发布

您现在位置:Python中文网/ 问答频道 /正文

分组之后,我想创建一个新列,其中包含时间序列中过去条目的唯一值。你知道吗

尝试使用努尼克变换,但它给出了整个组的唯一值

data={'user':['a','a','b','a','b','a','a','b'],
'time':[1,1.1,1.2,1.2,1.3,1.3,1.3,1.3],'prod':   ['k','k','t','t','y','k','z','x']}
df=pd.DataFrame(data)
df
   user time    prod
0   a   1.0     k
1   a   1.1     k
2   b   1.2     t
3   a   1.2     t
4   b   1.3     y
5   a   1.3     k
6   a   1.4     z
7   b   1.4     x

现在我想要的是gropby('user',sort='time')和get number of unique “prod”列中的值逐条输入。你知道吗

预期产量:

user time    prod  uniq_ebe
0   a   1.0     k  1
1   a   1.1     k  1 
2   b   1.2     t  1
3   a   1.2     t  2
4   b   1.3     y  2
5   a   1.3     k  2
6   a   1.4     z  3
7   b   1.4     x  3

按用户排序(输出):

   user time    prod  unique_ebe
0   a   1.0     k     1
1   a   1.1     k     1
2   a   1.2     t     2
3   a   1.3     k     2
4   a   1.4     z     3
5   b   1.2     t     1
6   b   1.3     y     2
7   b   1.4     x     3

Tags: 目的dataframedfdatagettime时间序列
3条回答

您可以编写一个函数来执行此操作:

import numpy as np
def uniqueID(x):
    y = x[1:] != x[:-1]
    i = np.r_[np.where(y)[0], x.size-1]
    run_len,vals = np.diff(np.r_[-1, i]), x[i]
    cnt = np.unique(vals,return_counts=True)
    seq = np.concatenate([range(j) for i,j in zip(*cnt)])+1
    return np.repeat(seq[vals.argsort().argsort()],run_len)

df.assign(new=uniqueID(df.user.values)).sort_values('user')
Out: 
  user  time prod  new
0    a   1.0    k    1
1    a   1.1    k    1
3    a   1.2    t    2
5    a   1.4    z    3
2    b   1.2    t    1
4    b   1.3    y    2
6    b   1.4    x    3

此函数仅在user上工作:

 a.assign(new=uniqueID(a.user.values))
Out[460]: 
    user  new
0      2    1
1      2    1
2      2    1
3      1    1
4      1    1
5      1    1
6      3    1
7      3    1
8      1    2
9      2    2
10     2    2
11     1    3
12     4    1
13     3    2
14     3    2
15     1    4
16     1    4
17     3    3
18     2    3

IIUC,使用groupbycumcount累计计算唯一值。那么,就reindex

df.drop_duplicates(['user', 'prod'])\
  .groupby('user')['prod']\
  .cumcount()\
  .add(1)\
  .reindex(df.index)\
  .ffill()

  user  time prod  uniq_sbe
0    a   1.0    k       1.0
1    a   1.1    k       1.0
2    b   1.2    t       1.0
3    a   1.2    t       2.0
4    b   1.3    y       2.0
5    a   1.3    z       3.0
6    b   1.3    x       3.0

我认为这里应该有一点修改拉斐尔的答案,每一组向前填充:

df['uniq_ebe'] = (df.drop_duplicates(['user', 'prod'])
                    .groupby('user')['prod']
                    .cumcount()
                    .add(1)
                    .reindex(df.index)
                    .groupby(df['user'])
                    .ffill()
                    .astype(int))
print (df)
  user  time prod  uniq_ebe
0    a   1.0    k         1
1    a   1.1    k         1
2    b   1.2    t         1
3    a   1.2    t         2
4    b   1.3    y         2
5    a   1.3    k         2
6    a   1.3    z         3
7    b   1.3    x         3

相关问题 更多 >