【问题标题】:how to find nunique values entry by entry within a group?如何在组内逐个条目查找唯一值条目?
【发布时间】:2020-12-30 05:26:40
【问题描述】:

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

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

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') 并获取唯一的数量 '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

【问题讨论】:

    标签: python python-3.x pandas pandas-groupby


    【解决方案1】:

    我认为这里应该稍微修改一下 rafael 的答案,每组向前填充:

    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
    

    【讨论】:

    • 感谢您的回答...我已经更新了匹配问题的问题...尝试您的答案在第 5 行给出了错误的答案...
    • @ArulDhina - 你能解释一下为什么会有2 吗?
    • 因为在用户组中的第三个条目之前有两个唯一值-a...我也会更新问题
    • 我现在说清楚了吗...?我不知道如何解释它,但我想逐个条目地获取唯一值条目,正如我在用户排序中显示的那样,以使其清楚......
    • @ArulDhina - 所以还是不行?如果是,您能否显示数据以查看问题出在哪里?
    【解决方案2】:

    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
    

    【讨论】:

    • 在重复输入时没有工作不一致...?请帮助
    【解决方案3】:

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

    import numpy as np
    def rle(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=rle(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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 2023-01-27
      • 2017-09-10
      • 1970-01-01
      • 2010-12-05
      相关资源
      最近更新 更多