所以我有以下数据框:
Period group ID
20130101 A 10
20130101 A 20
20130301 A 20
20140101 A 20
20140301 A 30
20140401 A 40
20130101 B 11
20130201 B 21
20130401 B 31
20140401 B 41
20140501 B 51
我需要计算去年按group
有多少个不同的ID
。所以我想要的输出如下所示:
Period group num_ids_last_year
20130101 A 2 # ID 10 and 20 in the last year
20130301 A 2
20140101 A 2
20140301 A 2 # ID 30 enters, ID 10 leaves
20140401 A 3 # ID 40 enters
20130101 B 1
20130201 B 2
20130401 B 3
20140401 B 2 # ID 11 and 21 leave
20140501 B 2 # ID 31 leaves, ID 51 enters
期间采用日期时间格式。我尝试了很多事情:
df.groupby(['group','Period'])['ID'].nunique() # Get number of IDs by group in a given period.
df.groupby(['group'])['ID'].nunique() # Get total number of IDs by group.
df.set_index('Period').groupby('group')['ID'].rolling(window=1, freq='Y').nunique()
但最后一个是不可能的。有什么简单的方法可以做到这一点吗?我想可能是 cumcount() 和 pd.DateOffset 的某种组合,或者可能是 ge(df.Period - dt.timedelta(365)) code>,但我找不到答案。
谢谢。
编辑:添加了这样一个事实:我可以在给定的Period
中找到多个ID
最佳答案
查看您的数据结构,我猜您有许多重复项,因此请先删除它们。 drop_duplicates
往往很快
我假设df['Period']
列的 dtype 为 datetime64[ns]
df = df.drop_duplicates()
results = dict()
for start in df['Period'].drop_duplicates():
end = start.date() - relativedelta(years=1)
screen = (df.Period <= start) & (df.Period >= end) # screen for 1 year of data
singles = df.loc[screen, ['group', 'ID']].drop_duplicates() # screen for same year ID by groups
x = singles.groupby('group').count()
results[start] = x
results = pd.concat(results, 0)
results
ID
group
2013-01-01 A 2
B 1
2013-02-01 A 2
B 2
2013-03-01 A 2
B 2
2013-04-01 A 2
B 3
2014-01-01 A 2
B 3
2014-03-01 A 2
B 1
2014-04-01 A 3
B 2
2014-05-01 A 3
B 2
这样更快吗?
附:如果df['Period']
不是日期时间:
df['Period'] = pd.to_datetime(df['Period'],format='%Y%m%d', errors='ignore')
关于python - pandas 中按组划分的独特值的一年滚动计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59687779/