首页 > 解决方案 > 在 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/2020并且1/4/2020colB.

标签: pythonpandas

解决方案


一般的方法是这样的:

# 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(2)datedate

('ColA', 'ColB_std')现在我们已经标准化了日期列,我们只需要计算每对存在多少个元素(3),从中获取ColA计数为 3 或更多的元素(4),然后过滤数据帧(5)

但是,这不支持重复的 对('ColA', 'ColB'),因为您需要先执行此操作:

df2 = df.drop_duplicates(["ColA", "ColB"])

继续df2在步骤 1、2、3 和 4 中使用它,最后df在步骤 5 中过滤实数。

以前,我回答说你也可以这样做

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


推荐阅读