【问题标题】:Create a new column containing time since last event in pandas在熊猫中创建一个包含自上次事件以来的时间的新列
【发布时间】:2018-09-29 07:55:08
【问题描述】:

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

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

IDdateMultiIndex

问题是,我想创建两个新列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

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

计算是根据ID 进行的,事件是不相关的。

【问题讨论】:

  • event1和event2有关系吗?是否应该按 ID 进行计算?
  • 为什么会有空值(-)?他们的逻辑是什么?
  • @Joost 事件是独立的,计算是按照ID。我要编辑这个问题。感谢您的提问
  • @RafaelC - 的含义是Nonepandas 中的等价物Not a date time
  • 我知道。我问为什么会有空值?例如,为什么time_1 的第一个值不是零,而第二个值不是2016-02-072016-01-03 之间的差异?这是什么逻辑?

标签: python python-3.x pandas


【解决方案1】:

如果您重置索引以便 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()

给我

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

之所以有效,是因为(使用 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]

然后我们按 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]

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

df["time_1"] = df["time_1"].dt.days
df["time_2"] = df["time_2"].dt.days

如果您愿意,可以使用浮点数而不是 timedeltas。

【讨论】:

  • 你能添加代码来取消设置索引然后恢复它们吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
  • 2015-05-28
相关资源
最近更新 更多