给定开始和停止日期当天的活动项目计数



我有一个包含2列的数据帧,与下面类似。

+------+-------------+------------+
| id    | start_date |  stop_date |
+------+-------------+------------+
| Foo   | 2019-06-01 | 2019-06-03 | 
| Bar   | 2019-06-07 | 2019-06-10 | 
| Pop   | 2019-06-09 | 2019-06-11 |          
| Bob   | 2019-06-13 |            | 
| Tom   | 2019-06-01 | 2019-06-05 |            
| Tim   | 2019-06-04 | 2019-06-05 |            
| Ben   | 2019-06-07 | 2019-06-09 |            
| Ted   | 2019-06-08 | 2019-06-09 |            
+------+------------+-------------+

我需要返回2个df,其中一个包含日期范围内的活动项目数(以下示例(

+------------+-------+
|    Day     |Active |
+------------+-------+
| 2019-06-01 |    2  |
| 2019-06-02 |    2  |
| 2019-06-03 |    2  |   
| 2019-06-04 |    2  |
| 2019-06-05 |    2  |
| 2019-06-06 |    0  |
| 2019-06-07 |    2  |
| 2019-06-08 |    3  |
| 2019-06-09 |    4  |     
| 2019-06-10 |    2  |         
| 2019-06-11 |    1  |          
| 2019-06-12 |    0  |         
| 2019-06-13 |    1  |         
| 2019-06-14 |    1  |
| 2019-06-15 |    1  |        
+------------+-------+

另一个返回df,其中包含给定日期的活动项2019-06-10返回df:

| Bar   | 2019-06-07 | 2019-06-10 | 
| Pop   | 2019-06-09 | 2019-06-11 |

到目前为止,我已经尝试返回第二个例子:

active_date = pd.Timestamp('2019-06-10')
df_active = df[(df['start_date'] <= active_date) & ((df["stop_date"].isnull()) | (df["stop_date"] > active_date))]`

感谢您的帮助!

您可以这样做:

df[["start_date", "stop_date"]] = df[["start_date", "stop_date"]].apply(pd.to_datetime)
df = df.ffill(axis=1)
df["days"] = [
pd.date_range(s, e, freq="D") for s, e in zip(df["start_date"], df["stop_date"])
]
df2 = (
df.explode("days")
.groupby("days")["id"]
.nunique()
.reindex(pd.date_range(df["start_date"].min(), df["stop_date"].max()), fill_value=0)
)

输出:

2019-06-01    2
2019-06-02    2
2019-06-03    2
2019-06-04    2
2019-06-05    2
2019-06-06    0
2019-06-07    2
2019-06-08    3
2019-06-09    4
2019-06-10    2
2019-06-11    1
2019-06-12    0
2019-06-13    1
Freq: D, Name: id, dtype: int64

并且,使用pd.IntervalIndex:

active_date = pd.Timestamp('2019-06-10')
df[
pd.IntervalIndex.from_arrays(df["start_date"], df["stop_date"]).contains(
active_date
)
].drop("days", axis=1)

输出:

id start_date  stop_date
1  Bar 2019-06-07 2019-06-10
2  Pop 2019-06-09 2019-06-11

最新更新