如何计算熊猫行之间的日期差异

时间:2021-03-25 23:07:43

标签: python pandas

我有一个看起来像这样的数据框。

<头>
ID 开始 结束
1 2020-12-13 2020-12-20
1 2020-12-26 2021-01-20
1 2020-02-20 2020-02-21
2 2020-12-13 2020-12-20
2 2021-01-11 2021-01-20
2 2021-02-15 2021-02-26

使用熊猫,我试图按 ID 分组,然后从前一行的结束日期减去当前行的开始日期。

如果差值大于 5 则返回 True

我是熊猫的新手,我一整天都在努力解决这个问题。

1 个答案:

答案 0 :(得分:0)

两个假设:

  1. 差值大于 5 是指 5 天
  2. 你的意思是绝对差异

所以我从这个数据框开始,我在其中添加了“above_5_days”列。

df
   ID      start        end above_5_days
0   1 2020-12-13 2020-12-20         None
1   1 2020-12-26 2021-01-20         None
2   1 2020-02-20 2020-02-21         None
3   2 2020-12-13 2020-12-20         None
4   2 2021-01-11 2021-01-20         None
5   2 2021-02-15 2021-02-26         None

这将是用于对每个 ID-group 应用操作的 groupby 对象

id_grp = df.groupby("ID")

以下是将应用于每个子集的操作

def calc_diff(x):

    # this shifts the end times down by one row to align the current start with the previous end
    to_subtract_from = x["end"].shift(periods=1) 
    diff = to_subtract_from - x["start"] # subtract the start date from the previous end

    # sets the new column to True/False depending on condition
    # if you don't want the absolute difference, remove .abs()
    x["above_5_days"] = diff.abs() > to_timedelta(5, unit="D") 
    return x

现在将其应用于整个组并将其存储在 newdf 中

newdf = id_grp.apply(calc_diff)
newdf
   ID      start        end  above_5_days
0   1 2020-12-13 2020-12-20         False
1   1 2020-12-26 2021-01-20          True
2   1 2020-02-20 2020-02-21          True
3   2 2020-12-13 2020-12-20         False
4   2 2021-01-11 2021-01-20          True
5   2 2021-02-15 2021-02-26          True

>>>>>>> 我应该指出:

在这种情况下,只有 False 值,因为向下移动每个组的结束列将在列的第一行中生成 NaN 值,从中减去时返回 NaN 值。所以 False 值只是 None 的布尔版本。

这就是为什么,我会亲自将函数更改为:

def calc_diff(x):

    # this shifts the end times down by one row to align the current start with the previous end
    to_subtract_from = x["end"].shift(periods=1) 
    diff = to_subtract_from - x["start"] # subtract the start date from the previous end

    # sets the new column to True/False depending on condition
    x["above_5_days"] = diff.abs() > to_timedelta(5, unit="D") 
    x.loc[to_subtract_from.isna(), "above_5_days"] = None
    return x

重新运行时,您可以看到,如果移动结束时间为 NaN,则 return 语句之前的额外行会将新列中的值设置为 NaN。

newdf = id_grp.apply(calc_diff)
newdf
   ID      start        end  above_5_days
0   1 2020-12-13 2020-12-20           NaN
1   1 2020-12-26 2021-01-20           1.0
2   1 2020-02-20 2020-02-21           1.0
3   2 2020-12-13 2020-12-20           NaN
4   2 2021-01-11 2021-01-20           1.0
5   2 2021-02-15 2021-02-26           1.0
相关问题