【问题标题】:All combination date differences in pandas column熊猫列中的所有组合日期差异
【发布时间】:2022-01-09 21:57:31
【问题描述】:

我有以下包含许多日期的数据框。我想:

sales_agents["hire_date"]


  0    2017-04-01 00:00:00

  1    2017-05-03 00:00:00

  2    2017-10-17 00:00:00

  Name: hire_date, dtype: object

我想获取第 0 行到第 n 行的 DAYS 差:

output = [(2017-04-01 - 2017-05-03), (2017-04-01 - 2017-10-17), (2017-05-03 - 2017-10-17)]

结果应该以 DAYS 为单位,我想得到除自身之外的所有可能组合的差异。

你能帮忙吗?

【问题讨论】:

    标签: python pandas date adjacency-matrix


    【解决方案1】:

    可以使用交叉合并和 numpy 外减法做一个邻接矩阵。代码如下

    g, h = df.merge(df, how='cross').to_numpy().T
    g=np.unique(g)
    h=np.unique(h)
    
    pd.DataFrame(np.subtract.outer(g, g), h, h) 
    
        
    
                 2017-04-01 2017-05-03 2017-10-17
    2017-04-01     0 days   -32 days  -199 days
    2017-05-03    32 days     0 days  -167 days
    2017-10-17   199 days   167 days     0 days
    

    【讨论】:

    • 谢谢你!它确实有帮助。我在函数 np.subtract.outer 上收到错误为 NotImplementedError:
    • 你用的是什么版本,这个结果完美无缺
    • 我正在使用这个版本:'1.20.3'
    【解决方案2】:

    一种选择是进行'cross' 合并并使用索引过滤到基本上上三角形,这样您就不会重复计算 AB 和 BA 合并(第 1 行与第 2 行,第 2 行与第 1 行),并且还排除 AA 合并(第 1 行与自身合并)。

    然后,结果会显示差异(以天为单位)以及用于形成差异的两个日期。如果您想记录这些日期的来源,可以删除代码中的 .drop(columns=['index_x', 'index_y']) 部分。

    样本数据

    import pandas as pd
    df = pd.DataFrame({'date': ['2017-04-01 00:00:00', '2017-05-03 00:00:00', 
                                '2017-10-17 00:00:00']})
    df['date'] = pd.to_datetime(df.date)
    

    代码

    res = (pd.merge(df[['date']].reset_index(), df[['date']].reset_index(), how='cross')
             .query('index_x > index_y')
             .drop(columns=['index_x', 'index_y']))
    
    res['diff'] = (res['date_y'] - res['date_x']).dt.days
    
    print(res)
    #      date_x     date_y  diff
    #3 2017-05-03 2017-04-01   -32
    #6 2017-10-17 2017-04-01  -199
    #7 2017-10-17 2017-05-03  -167
    

    或者,您可以使用外部减法在 numpy 中执行此操作,然后提取值的下三角形(不包括对角线 k=1)。由于这些是以纳秒为单位计算的,因此我们需要将 10**9*60*60*24 转换为天数

    import numpy as np
    
    arr = df['date'].to_numpy()[:, None] - df['date'].to_numpy()[None, :]
    days = arr[np.triu_indices(arr.shape[0], k=1)]/(10**9*60*60*24)
    
    days
    #array([ -32, -199, -167], dtype='timedelta64[ns]')
    

    【讨论】:

    • 您的熊猫解决方案很棒。谢谢你!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2021-11-10
    • 2019-01-03
    • 2017-03-21
    • 1970-01-01
    相关资源
    最近更新 更多