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
我有一个如下所示的输入数据框:
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