【问题标题】:How do I reset the count using the pandas diff() function when a condition from another column is satisfied?当满足另一列的条件时,如何使用 pandas diff() 函数重置计数?
【发布时间】:2021-11-10 22:45:06
【问题描述】:

我正在尝试计算日期之间的天数(累计),(由表示为 id 的列分组),但是,我想在满足条件时重置计数器。

下面我有以下数据框:

     reset_day category       date     id  tdelta
0            N      low 2019-09-04  16876     NaN
1            N      low 2019-09-05  16876     NaN
2            N      low 2019-09-06  16876     NaN
3            N      low 2019-09-07  16876     NaN
4            N      low 2019-09-08  16876     NaN
...        ...      ...        ...    ...     ...
5144         Y   medium 2021-05-23  17612     0.0
5145         Y     high 2021-05-23  23406     0.0
5146         Y     high 2021-05-23  21765     0.0
5147         Y   medium 2021-05-23  19480     0.0
5148         Y   medium 2021-05-23   9066     0.0

在这里,我想将值输入“tdelta”列,其中的值当前为 NaN。此列计算每个 id 的“日期”列之间的天数。

但是,我正在努力尝试根据“reset_day”列重置计数。如果列值为“Y”,则该特定 id 的计数应重新开始。在这种情况下,您已经可以在 tdelta 列中看到值 0。

我之前在类似的数据帧上尝试过以下操作,方法是创建另一个表示为 test t delta 的列:

example = example.sort_values(by="date")
example['date'] = pd.to_datetime(example['date'], format='%Y/%m/%d')
example['test tdelta'] = example.groupby('id')['date'].diff() / np.timedelta64(1, 'D')
example['test tdelta'] = example['test tdelta'].fillna(0) 

但是,这只是计算每个 id 日期之间的天数,并在没有我需要的重置的情况下填充缺失的值。

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: python pandas dataframe numpy time-series


    【解决方案1】:

    我认为根据重置日期创建一个额外的分组列可能是您想要的。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({'reset_day':['N','N','Y','N','N','Y','Y','Y','Y','Y'],
                       'category':['low','low','low','low','low','medium','high','high','medium','medium'],
                       'date':['2019-09-04','2019-09-05','2019-09-06','2019-09-07','2019-09-08','2021-05-23','2021-05-23','2021-05-23','2021-05-23','2021-05-23'],
                       'id':[16876,16876,16876,16876,16876,17612,23406,21765,19480,9066]
                       })
    
    
    df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d')
    df = df.sort_values(['id','date'])
    
    #create extra grouping column based on reset day
    df['reset_group'] = df['reset_day'].replace({'N':False,'Y':True})
    df['reset_group'] = df.groupby('id')['reset_group'].cumsum()
    
    #use extra grouping column when calculating differences
    df['tdelta'] = df.groupby(['id','reset_group'])['date'].diff() / np.timedelta64(1, 'D')
    df['tdelta'] = df.groupby(['id','reset_group'])['tdelta'].cumsum().fillna(0)
    
    print(df)
    
      reset_day category       date     id  reset_group  tdelta
    9         Y   medium 2021-05-23   9066            1     0.0
    0         N      low 2019-09-04  16876            0     0.0
    1         N      low 2019-09-05  16876            0     1.0
    2         Y      low 2019-09-06  16876            1     0.0
    3         N      low 2019-09-07  16876            1     1.0
    4         N      low 2019-09-08  16876            1     2.0
    5         Y   medium 2021-05-23  17612            1     0.0
    8         Y   medium 2021-05-23  19480            1     0.0
    7         Y     high 2021-05-23  21765            1     0.0
    6         Y     high 2021-05-23  23406            1     0.0
    

    【讨论】:

    • 感谢您的解决方案。如果您不介意,我还有一个问题:假设我想从重置日开始倒数,我会创建额外的列来实现这一点吗?
    • 在创建了额外的分组列之后,您是否可以将数据以相反的顺序重新排序?那么它应该基本上是相同的逻辑,找到差异和累积和,然后如果需要再次对最终结果进行排序。
    • 是的,你没看错,就是这么简单df = df.sort_values(by='date', ascending=False)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 2021-06-19
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多