在 pandas 中按日期累计计算唯一值并添加一列

Counting unique values cumulatively by date in pandas and add a column

我有以下数据。我想创建一个列,它是按日期从“从”和“到”列中的唯一值数量的累积总和。

当前数据帧

id  date         from   to      
A   01/01/2020  alice  bob        
A   01/01/2020  alice  carl        
A   01/02/2020  jim    peter
A   01/02/2020  jim    jen
B   01/02/2020  mary   john
B   01/03/2020  john   max
B   01/03/2020  mike   jane
B   01/03/2020  jane   jim
C   01/02/2020  xavier jim
C   01/02/2020  jim    alice
C   01/03/2020  alice  bob
C   01/03/2020  manny  lily
C   01/04/2020  rosa   bob
.       .         .      .
.
.
.
.
.

我要

id       date   cum_sum
A   01/01/2020  3
A   01/02/2020  6 
B   01/02/2020  2
B   01/03/2020  7
C   01/02/2020  3
C   01/03/2020  6
C   01/04/2020  7
.       .       .
.
.
.
.
.

我试过类似下面的方法

cum_sum = df.groupby(['id', pd.Grouper(freq='D', key='date')])['from', 'to_'].nunique.cumsum()

但没有成功。任何帮助将不胜感激!

更新 我已经尝试过这个有效但我只能添加一列“来自”。知道如何添加“to”吗??

df1 = (df.groupby(['id','date'])['from']
         .apply(list)
         .groupby(level=0)
         .apply(np.cumsum)
         .apply(lambda x: len(set(x)))
         .reset_index(name='cum_sum'))

您可以 melt DataFrame,groupby.agg 为每个 id-date 对构造列表,然后再次使用 groupby 应用 numpy.cumsum 连接列出。然后再次使用 apply 来获取每个 id 的唯一集合的长度:

import numpy as np
id_vars = df.columns.difference(['from','to'])
cols = ['id','date']
out = (df.melt(id_vars=id_vars, value_name='cum_sum')
       .groupby(cols)['cum_sum'].agg(list)
       .groupby(level=0).apply(np.cumsum)
       .apply(lambda x: len(set(x))).reset_index())    

输出:

  id        date  cum_sum
0  A  01/01/2020        3
1  A  01/02/2020        6
2  B  01/02/2020        2
3  B  01/03/2020        6
4  C  01/02/2020        3
5  C  01/03/2020        6
6  C  01/04/2020        7