创建一个新列,其中包含自pandas

时间:2018-04-18 23:25:11

标签: 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

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,且事件无关。

1 个答案:

答案 0 :(得分:3)

如果您重置索引以便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因为它有两个不同的Trues它更有趣)首先我们只选择" start"次:

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]

之后我们只需要减去得到timedeltas。你可以使用

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

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