基于开始日期和结束日期的滚动groupby nunique计数

2024-04-27 04:28:26 发布

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

我有一个具有唯一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_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

非常感谢任何提示或帮助


Tags: 数据方法keyiddataframezipstartend
3条回答

也许你可以列出从开始到结束的所有月份,爆发并最终计数

import pandas as pd

df = 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]})

df["list"] = df.apply(lambda x: list(range(x["start_month"], x["end_month"]+1)), 
                      axis=1)

df = df.explode("list")

df.groupby("list")["ZIP_KEY"].nunique()

一个选项是重新创建数据框,将范围扩展到范围内的所有月份,并在每一行中复制键。然后您可以使用普通的groupby

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.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

相关问题 更多 >