一般的做法是这样的:
# 1. To make sure the dates are sorted
df = df.sort_values(["ColA", "ColB"])
# 2. Standardize the dates by offseting them
df["ColB_std"] = df["ColB"] - pd.to_timedelta(range(df.shape[0]), 'day')
# 3. Counting each instance of ColA and standardized date
s = df.groupby(["ColA", "ColB_std"])["ColB_std"].count()
# 4. Getting elements from ColA that have at least 1 sequence of at least length 3
colA = s[ s >= 3 ].index.get_level_values(0).unique().values
# 5. Filtering the dataframe
df[ df["ColA"].isin(colA) ]
您希望 ColAs 有 3 个连续日期。或者你可以像你想要的ColAs 那样想它,其中有date、date + 1 day 和date + 2 days 的序列。通过按照 ColA 和 ColB (1) 对数据框进行排序,我们知道在您要检查的情况下,date + 1 day 将始终跟随 date,而 date + 2 days 将是以下那个.
这样,您可以通过删除与行对应的n 天来标准化日期。因此,date、date + 1 day 和 date + 2 days 的序列变为 date、date 和 date(2)。
现在我们已经标准化了日期列,我们只需要计算每对 ('ColA', 'ColB_std') 存在多少个元素(3),从 ColA 中获取计数为 3 或更多(4),并过滤数据框(5)。
但是,这不支持重复的 ('ColA', 'ColB') 对,因为您需要先执行此操作:
df2 = df.drop_duplicates(["ColA", "ColB"])
在步骤 1、2、3 和 4 中继续使用这个 df2,最后在步骤 5 中过滤真正的 df。
之前我回答说你也可以这样做:
# To make sure the dates are sorted
df = df.sort_values(["ColA", "ColB"])
# Calculating the difference between dates inside each group
s = df.groupby("ColA")["ColB"].diff().dt.days
# Filtering the dataframe
df[ ((s == 1) & (s.shift(1) == 1)).groupby(df["ColA"]).transform("any") ]
这个想法是,在s 中,差异总是在前一个日期和当前日期之间。但是,这并不能确保有 3 个连续日期,只有 2 个。通过将系列移动 1,您可以确保当前不同的日期和前一个日期是 1 [(s == 1) & (s.shift(1) == 1)]。
之后,我只需要groupby(df["ColA"]),然后使用transform("any") 检查组内的任何元素是否为真。