创建一个新列,其中包含自 pandas 中上次事件以来的时间

nan*_*nue 1 python python-3.x pandas

我有一个具有以下结构的 pandas 数据框:

ID    date           event_1   event_2 
 1    2016-01-03     False     False
      2016-02-07     True      False
      2016-02-18     False     True
 2    2016-01-01     False     True
      2016-01-04     False     False
      2016-02-02     True      False
      2016-02-04     False     False
      2016-02-05     False     True
Run Code Online (Sandbox Code Playgroud)

ID并且date是一个MultiIndex.

问题是,我想创建两个新列time_1time_2。这些列应显示自相应事件以来经过的时间,例如

ID    date           event_1     event_2   time_1    time_2
 1    2016-01-03     False       False     -          -
      2016-02-07     True        False     0          -
      2016-02-18     False       True      11         0
 2    2016-01-01     False       True      -          0
      2016-01-04     False       False     -          3
      2016-02-02     True        False     0          32
      2016-02-04     False       False     2          34
      2016-02-05     False       True      3          0
Run Code Online (Sandbox Code Playgroud)

pandas假设日期是索引,如何创建一个在 中计算此值的函数?

计算是按每个事件进行的ID,与事件无关。

DSM*_*DSM 6

如果您重置索引,使 ID 和日期成为列(只是为了更容易引用它们 -df.index.get_level_values("date")有点笨拙),并且确保 df["date"] 是真正的日期时间列而不是字符串,我认为这很漂亮直截了当:

df["time_1"] = df["date"] - df["date"].where(df["event_1"]).groupby(df["ID"]).ffill()
df["time_2"] = df["date"] - df["date"].where(df["event_2"]).groupby(df["ID"]).ffill()
Run Code Online (Sandbox Code Playgroud)

给我

In [173]: df
Out[173]: 
   ID       date  event_1  event_2  time_1  time_2
0   1 2016-01-03    False    False     NaT     NaT
1   1 2016-02-07     True    False  0 days     NaT
2   1 2016-02-18    False     True 11 days  0 days
3   2 2016-01-01    False     True     NaT  0 days
4   2 2016-01-04    False    False     NaT  3 days
5   2 2016-02-02     True    False  0 days 32 days
6   2 2016-02-04    False    False  2 days 34 days
7   2 2016-02-05    False     True  3 days  0 days
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为(使用 event_2 因为它更有趣,因为它有两个不同的 True)首先我们只选择“开始”时间:

In [176]: df["date"].where(df["event_2"])
Out[176]: 
0          NaT
1          NaT
2   2016-02-18
3   2016-01-01
4          NaT
5          NaT
6          NaT
7   2016-02-05
Name: date, dtype: datetime64[ns]
Run Code Online (Sandbox Code Playgroud)

然后我们按 ID 分组并向前填充参考日期:

In [177]: df["date"].where(df["event_2"]).groupby(df["ID"]).ffill()
Out[177]: 
0          NaT
1          NaT
2   2016-02-18
3   2016-01-01
4   2016-01-01
5   2016-01-01
6   2016-01-01
7   2016-02-05
Name: date, dtype: datetime64[ns]
Run Code Online (Sandbox Code Playgroud)

之后我们只需减去即可得到时间增量。您可以使用

df["time_1"] = df["time_1"].dt.days
df["time_2"] = df["time_2"].dt.days
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以使用浮动而不是时间增量。