在熊猫数据框中查找连续的日子

时间:2020-01-29 11:00:42

标签: python pandas

我有一个数据框:

  ColA  ColB

0   A    1/2/2020 
1   A    1/3/2020       
2   A    1/4/2020
3   A    1/10/2020 
4   B    1/3/2020
5   B    1/19/2020
6   C    1/2/2020
7   C    1/7/2020 
8   D    1/8/2020

现在,我想在colA中找出系列的名称,该系列在colB中连续三天。

输出:

答案为A,因为它在1/2/2020中有1/3/20201/4/2020colB

1 个答案:

答案 0 :(得分:0)

一般方法如下:

# 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) ]

您希望ColA连续3个日期。或者,您可以像想要ColA那样datedate + 1 daydate + 2 days的序列来思考它。通过按ColA和ColB (1)对数据框进行排序,我们知道在要检查的情况下,date + 1 day将始终跟随date,而date + 2 days将是那个。

通过此操作,您可以通过删除n天对应于其行的日期来标准化日期。因此,datedate + 1 daydate + 2 days的序列变为datedatedate (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")检查组中是否有任何元素。