Python 基于开始日期和结束日期的滚动groupby nunique计数
我有一个具有唯一ID、开始日期和结束日期的数据帧。在一年中,ID可以启动、停止和重新启动 我想得到一年内groupby nunique的身份证计数。 目前,我可以为ID的开始日期计算唯一值,但如何准确合并结束日期Python 基于开始日期和结束日期的滚动groupby nunique计数,python,pandas,Python,Pandas,我有一个具有唯一ID、开始日期和结束日期的数据帧。在一年中,ID可以启动、停止和重新启动 我想得到一年内groupby nunique的身份证计数。 目前,我可以为ID的开始日期计算唯一值,但如何准确合并结束日期 fun = pd.DataFrame({'ZIP_KEY': ['A', 'B','C', 'A', 'B', 'A'], 'start_month': [1, 2, 2, 6, 8, 10], 'end_mo
fun = pd.DataFrame({'ZIP_KEY': ['A', 'B','C', 'A', 'B', 'A'],
'start_month': [1, 2, 2, 6, 8, 10],
'end_month': [4, 3, 7, 7, 12, 12]})
fun.groupby('start_month')['ZIP_KEY'].nunique()
start_month
1 1
2 2
3 0
4 0
5 0
6 1
7 0
8 1
9 0
10 1
11 0
12 0
基本上,如果一个ID从一月份开始到三月份结束,我希望它包含在二月份和三月份的计数中,而不仅仅是一月份,这就是我当前方法的操作方式
期望输出:
start_month
1 1
2 3
3 3
4 2
5 1
6 2
7 2
8 1
9 1
10 2
11 2
12 2
非常感谢任何提示或帮助 一个选项是重新创建数据帧,将范围扩展到范围内的所有月份,并在每一行中复制密钥。然后,您可以使用普通的
分组方式
df = pd.concat([pd.DataFrame({'month': range(st, en+1), 'key': k})
for k, st, en in zip(fun['ZIP_KEY'], fun['start_month'], fun['end_month'])])
df.groupby('month').key.nunique()
#month
#1 1
#2 3
#3 3
#4 2
#5 1
#6 2
#7 2
#8 1
#9 1
#10 2
#11 2
#12 2
#Name: key, dtype: int64
一个选项是重新创建数据框,将范围扩展到范围内的所有月份,并在每一行中复制键。然后,您可以使用普通的分组方式
df = pd.concat([pd.DataFrame({'month': range(st, en+1), 'key': k})
for k, st, en in zip(fun['ZIP_KEY'], fun['start_month'], fun['end_month'])])
df.groupby('month').key.nunique()
#month
#1 1
#2 3
#3 3
#4 2
#5 1
#6 2
#7 2
#8 1
#9 1
#10 2
#11 2
#12 2
#Name: key, dtype: int64
也许你可以列出从开始到结束的所有月份,爆发并最终计数
将熊猫作为pd导入
df=pd.DataFrame({'ZIP_KEY':['A','B','C','A','B','A'],
“开始月份”:[1,2,2,6,8,10],
‘月底’:[4,3,7,7,12]})
df[“list”]=df.apply(λx:list(范围(x[“开始月份”]、x[“结束月份”]+1)),
轴=1)
df=df.分解(“列表”)
df.groupby(“list”)[“ZIP_KEY”].nunique()
也许你可以列出从开始到结束的所有月份,分解并最终计数
将熊猫作为pd导入
df=pd.DataFrame({'ZIP_KEY':['A','B','C','A','B','A'],
“开始月份”:[1,2,2,6,8,10],
‘月底’:[4,3,7,7,12]})
df[“list”]=df.apply(λx:list(范围(x[“开始月份”]、x[“结束月份”]+1)),
轴=1)
df=df.分解(“列表”)
df.groupby(“list”)[“ZIP_KEY”].nunique()
将pd.IntervalIndex与pandas 1.0.0结合使用会有一些乐趣
ii = pd.IntervalIndex.from_arrays(fun['start_month'], fun['end_month'], closed='both')
monthrange = np.arange(1,13)
pd.Series(monthrange, index=monthrange).apply(lambda x: sum(ii.contains(x)))\
.rename_axis('months').rename('count')
输出:
months
1 1
2 3
3 3
4 2
5 1
6 2
7 2
8 1
9 1
10 2
11 2
12 2
Name: count, dtype: int64
使用pd.IntervalIndex和pandas 1.0.0有一点乐趣
ii = pd.IntervalIndex.from_arrays(fun['start_month'], fun['end_month'], closed='both')
monthrange = np.arange(1,13)
pd.Series(monthrange, index=monthrange).apply(lambda x: sum(ii.contains(x)))\
.rename_axis('months').rename('count')
输出:
months
1 1
2 3
3 3
4 2
5 1
6 2
7 2
8 1
9 1
10 2
11 2
12 2
Name: count, dtype: int64