DataFrame - 自上一个正值和上一个负值以来的时间

DataFrame - time since last positive and last negative value

我有一个如下所示的输入数据框:

df = pd.DataFrame.from_dict({"t": [1,2,3,4,5], 'val': [100, 5, -4, -9, 1], })

我需要计算以下两列,一列是自上一个正值以来的时间,一列是自上一个负值以来的时间:

df['t_since_neg'] = [np.nan, np.nan, np.nan, 1, 1]
df['t_since_pos'] =  [np.nan, 1, 1,2,3]

t列代表时间。我该怎么做呢?我知道它与 diff 有关,但我无法让它正常工作。

更新(跟进问题):如果我有一个额外的列'id',我将如何做到这一点,并且需要在每个组内分别进行计算,即每个组彼此独立?

解决方案

m = df.val > 0

df['t_since_neg'] = df['t'] - df['t'].where(~m).ffill().shift()
df['t_since_pos'] = df['t'] - df['t'].where( m).ffill().shift()

   t  val  t_since_neg  t_since_pos
0  1  100          NaN          NaN
1  2    5          NaN          1.0
2  3   -4          NaN          1.0
3  4   -9          1.0          2.0
4  5    1          1.0          3.0

已解释

要计算t_since_pos,首先屏蔽时间列中对应的val为负值的值,然后前向填充并转移到传播与最后一个正值对应的时间,最后从中减去这个原始时间栏。同样的方法可以用来计算t_since_neg

>>>  df['t'].where(m)
0    1.0
1    2.0
2    NaN
3    NaN
4    5.0
Name: t, dtype: float64

>>> .ffill().shift()
0    NaN
1    1.0
2    2.0
3    2.0
4    2.0
Name: t, dtype: float64