【问题标题】:Once a row is encountered, remove all rows within 40 days, then repeat一旦遇到一行,在 40 天内删除所有行,然后重复
【发布时间】:2021-11-26 14:10:47
【问题描述】:

我有以下数据框,按 ID 和日期排序:

df :

ID     Date
A      2019-01-02
A      2019-02-09
A      2019-02-20
A      2019-02-27
A      2019-03-16
A      2019-03-29
A      2019-04-17
A      2019-04-19
A      2019-05-26
A      2019-06-12
B      2017-01-01
B      ...

我想要的是,当我遇到一行时,删除所有在接下来的 40 天内具有日期的行,并从我遇到的下一个(未删除的)行开始重复。我希望每个 ID 都有。

例如 ID=A :

  • 我遇到第一行,日期是2019-01-02。 40 天后是2019-02-11,所以我严格删除这两个日期之间的所有日期行。所以第二行被删除(日期=2019-02-09
  • 然后,我查找带有Date >= 2019-02-11 的下一行(2019-02-11 是前40 天期限的结束)。我找到第三行,日期 = 2019-02-20。这是现在的参考日期,40 天后是2019-04-01。所以第 4、5、6 行被删除了
  • ...

请注意,当我遇到新行并且当前没有 40 天期限处于活动状态时,我的 40 天期限开始了。因此,并非所有 ID 的这些周期都相同。

这给出了以下输出数据集

ID     Date
A      2019-01-02
A      2019-02-20
A      2019-04-17
A      2019-06-12
B      2017-01-01
B      ...

提前致谢

【问题讨论】:

  • 您的问题含糊不清,考虑改写
  • @Luke 很难将所有细节都放在标题中。这就是为什么我将示例放在问题中,真正详细说明了问题。我找不到合适的标题,而不是“太模糊”,如果您有任何建议,我愿意提供建议
  • 所以您要确保您的数据框在 40 天内只有一个 ID 实例
  • 是的,但是周期不固定,当我遇到一行时开始(此行日期是 40 天周期的开始日期)并且没有其他 40 天周期处于活动状态。
  • 我怎么知道哪一行开始了句号? (问题不清楚)

标签: python pandas dataframe


【解决方案1】:

您可以循环遍历数据框以创建过滤器

import pandas as pd
import datetime 

# create your dataframe "df" here...
# with columns "ID" and "Date"

# make sure your Date is a datetime field!
df['Date'] = pd.to_datetime(df['Date'])

prev_id = None
prev_date = None
keep_rows = []

for _, row in df.iterrows():

    if row['ID'] == prev_id:
        delete = (row['Date'] - prev_date) < datetime.timedelta(days=40) 
        if delete:
            keep_rows.append(False)    
            continue
        
    keep_rows.append(True)
    prev_id = row['ID']
    prev_date = row['Date']

并像这样过滤您的数据框

df[keep_rows]

【讨论】:

  • 非常感谢您的回答。我想知道是否存在关于 Pandas 函数(而不是 iterrows)的任何答案(因为执行时间),但这已经对我有很大帮助
  • 如果您遇到执行时间问题,您可以使用 groupby 然后遍历每个分组数据帧的 Date 列来获取过滤器。我怀疑这可能不会快得多,您必须编写它并对其进行分析。您也可以尝试在仅限于“ID”和“日期”列的数据帧上使用 iterrows。再说一次,如果值得的话,说明一下
  • 对此的最终想法:您可以将 iterrows 替换为 itertuples,这也将加快您的速度。对于你的小例子,它快了 4 倍以上。 (我改变了解决方案)
  • 我在使用 itertuples 时遇到了一些问题,但它在使用 iterrows 时效果很好。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
相关资源
最近更新 更多