我想创建一个名为“inc”的变量,每次满足条件时(例如,Delta>=5),该变量都会按顺序递增,否则保持相同,并在每次遇到新组(本例中为 ID)时重置为 1 )。这是一个示例数据框:
from pandas import *
d={'rx': [1,1,1,1,1,2,2,2,2,2],
'vals': [1,2,3,8,10,1,10,20,21,22]}
df=DataFrame(d)
def diff_func(df):
return df.diff()
df['delta'] = df.groupby(['rx'])['vals'].apply(diff_func)
产生这个:
rx vals delta
1 1 NaN
1 2 1
1 3 1
1 8 5
1 10 2
2 1 NaN
2 10 9
2 20 10
2 21 1
2 22 1
所以现在我想创建一个名为“Event”的新列,稍后我将使用它对由 delta 分隔的每个 rx 值内的观察结果进行分组< 5:
rx vals delta Event
1 1 NaN 1
1 2 1 1
1 3 1 1
1 8 5 2
1 10 2 2
2 1 NaN 1
2 10 9 2
2 20 10 3
2 21 1 3
2 22 1 3
请注意,“event”在第一次出现 rx 时返回到 1。我习惯在 vbasic 或 SAS 中执行此操作,只需保留一个值,然后在每次满足阈值触发器时加 1。 Python 中是否有类似的简单解决方案?
通常的做法是先进行比较,然后进行累加。例如,类似:
>>> df["Event"] = (df["delta"] >= 5).groupby(df["rx"]).cumsum() + 1
>>> df
rx vals delta Event
0 1 1 NaN 1
1 1 2 1 1
2 1 3 1 1
3 1 8 5 2
4 1 10 2 2
5 2 1 NaN 1
6 2 10 9 2
7 2 20 10 3
8 2 21 1 3
9 2 22 1 3
之所以有效,是因为(为了简单起见,忽略 groupby,只关注
rx == 1
:) False == 0
和 True == 1
:
>>> df["delta"]
0 NaN
1 1
2 1
3 5
4 2
Name: delta, dtype: float64
>>> df["delta"] >= 5
0 False
1 False
2 False
3 True
4 False
Name: delta, dtype: bool
>>> (df["delta"] >= 5).cumsum()
0 0
1 0
2 0
3 1
4 1
Name: delta, dtype: int64
def diff_func(df:pd.DataFrame):
return df.assign(Event=df.delta.ge(5).cumsum().add(1))
df1.fillna(1).astype(int).groupby(['rx'],as_index=False).apply(diff_func)
┌───────┬───────┬───────┬───────┬───────┐
│ index │ rx │ vals │ delta │ Event │
│ int64 │ int32 │ int32 │ int32 │ int32 │
├───────┼───────┼───────┼───────┼───────┤
│ 0 │ 1 │ 1 │ 1 │ 1 │
│ 1 │ 1 │ 2 │ 1 │ 1 │
│ 2 │ 1 │ 3 │ 1 │ 1 │
│ 3 │ 1 │ 8 │ 5 │ 2 │
│ 4 │ 1 │ 10 │ 2 │ 2 │
│ 5 │ 2 │ 1 │ 1 │ 1 │
│ 6 │ 2 │ 10 │ 9 │ 2 │
│ 7 │ 2 │ 20 │ 10 │ 3 │
│ 8 │ 2 │ 21 │ 1 │ 3 │
│ 9 │ 2 │ 22 │ 1 │ 3 │
├───────┴───────┴───────┴───────┴───────┤
│ 10 rows 5 columns │
└───────────────────────────────────────┘