【问题标题】:Pandas: New value based on time intervalPandas:基于时间间隔的新值
【发布时间】:2022-01-05 11:11:17
【问题描述】:

想象这样一种情况,每次客户访问我们时,他们都应该支付 100 美元,除非自上次付款后已过去

知道每个客户的约会日期,是否可以预测应该付款的约会?

以下面的数据框为例:

pd.DataFrame({
  'dd_mm_aa': {
    0: '01/12/21',
    1: '01/12/21',
    2: '10/12/21',
    3: '10/12/21',
    4: '03/01/22',
    5: '03/01/22',
    6: '03/01/22',
    7: '15/01/22',
    8: '15/01/22',
    9: '06/02/22'},
  'name': {0: 'John',
    1: 'Mary',
    2: 'John',
    3: 'Peter',
    4: 'John',
    5: 'Mary',
    6: 'Peter',
    7: 'Mary',
    8: 'John',
    9: 'John'}
    })

我能够使用下面的代码在客户第一次预约时添加要支付的价值。

# Adding 150 at firts appearance of a patient
df['dd_mm_aa'] = pd.to_datetime(df['dd_mm_aa'], dayfirst=True)
df.loc[df.groupby('name')["dd_mm_aa"].rank() == 1, 'value'] = 100

之后,dataframe如下:

dd_mm_aa     name    value
01/12/21    John    100
01/12/21    Mary    100
10/12/21    John    
10/12/21    Peter   100
03/01/22    John    
03/01/22    Mary    
03/01/22    Peter   
15/01/22    Mary    
15/01/22    John    
06/02/22    John    

但是,考虑>30天的时间间隔,最终输出应该是:

dd_mm_aa    name    value
01/12/21    John    100
01/12/21    Mary    100
10/12/21    John    
10/12/21    Peter   100
03/01/22    John    100
03/01/22    Mary    100
03/01/22    Peter   
15/01/22    Mary    
15/01/22    John    
06/02/22    John    100

【问题讨论】:

    标签: python pandas dataframe datetime pandas-groupby


    【解决方案1】:

    使用迭代方法:

    from datetime import timedelta
    
    last_paid = {}
    def check_paid(r):
        if r['name'] not in last_paid:
            last_paid[r['name']] = r['dd_mm_aa']
            r['value'] = 100
        elif last_paid[r['name']] + timedelta(days=30) < r['dd_mm_aa']:
            last_paid[r['name']] = r['dd_mm_aa']
            r['value'] = 100
        return r
    
    df['dd_mm_aa'] = pd.to_datetime(df['dd_mm_aa'], dayfirst=True)
    df = df.apply(check_paid, axis=1)
    

    输出:

        dd_mm_aa    name    value
    0   2021-12-01  John    100.0
    1   2021-12-01  Mary    100.0
    2   2021-12-10  John    NaN
    3   2021-12-10  Peter   100.0
    4   2022-01-03  John    100.0
    5   2022-01-03  Mary    100.0
    6   2022-01-03  Peter   NaN
    7   2022-01-15  Mary    NaN
    8   2022-01-15  John    NaN
    9   2022-02-06  John    100.0
    

    【讨论】:

    • 如果有人能找到一种矢量化方法来提高速度性能,那就太好了
    • 您基本上需要为每个用户的 timedelta 系列重置一个 cumsum - 我没有看到避免迭代的方法,请参见例如Restart cumsum and get index if cumsum more than value上的答案。
    • 谢谢你们。我一直在尝试不同的方法(甚至使用 cumsum),但没有任何方法能 100% 奏效。我会坚持@Ming 的回答。
    猜你喜欢
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 2021-11-19
    • 1970-01-01
    • 2019-02-25
    • 2021-10-04
    • 1970-01-01
    相关资源
    最近更新 更多