对于这些问题,我通常的处理方法是围绕更改累加器的事件进行思考。我们看到的每个新的“ stdt”都会使计数增加+1;我们看到的每个“
enddt”都加-1。(第二天加-1,至少如果我解释您的方式“在两者之间”。某些时候,我认为我们应该禁止过于含糊地使用该词。)
IOW,如果我们将您的框架变成类似
>>> df.head() cid jid change date0 1 100 1 2015-01-061 1 101 1 2015-01-0721 1 100 -1 2015-01-1622 1 101 -1 2015-01-1717 1 117 1 2015-03-01
那么我们想要的只是
change(经过适当的重组后)的累积总和。例如,类似
df["enddt"] += timedelta(days=1)df = pd.melt(df, id_vars=["cid", "jid"], var_name="change", value_name="date")df["change"] = df["change"].replace({"stdt": 1, "enddt": -1})df = df.sort(["cid", "date"])df = df.groupby(["cid", "date"],as_index=False)["change"].sum()df["count"] = df.groupby("cid")["change"].cumsum()new_time = pd.date_range(df.date.min(), df.date.max())df_parts = []for cid, group in df.groupby("cid"): full_count = group[["date", "count"]].set_index("date") full_count = full_count.reindex(new_time) full_count = full_count.ffill().fillna(0) full_count["cid"] = cid df_parts.append(full_count)df_new = pd.concat(df_parts)
这给了我类似的东西
>>> df_new.head(15) count cid2015-01-03 0 12015-01-04 0 12015-01-05 0 12015-01-06 1 12015-01-07 2 12015-01-08 2 12015-01-09 2 12015-01-10 2 12015-01-11 2 12015-01-12 2 12015-01-13 2 12015-01-14 2 12015-01-15 2 12015-01-16 1 12015-01-17 0 1
关于您的期望可能存在一对一的差异;您可能对如何
jid在同一时间窗口中处理多个重叠的s有不同的想法(此处将它们计为2);但是即使必须微调细节,处理事件的基本思想也应被证明是有用的。