我将尝试解释简单。我有一个这样的数据框有更多的列
d = {'Id': [1, 1, 1, 1, 2, 3, 3, 3], 'Val': ['Yes', 'Stop', 'Yes', 'Yes', 'Yes', 'Yes', 'Stop', 'Yes']}
df = pd.DataFrame(data=d)
Id Val
0 1 Yes
1 1 Stop
2 1 Yes
3 1 Yes
4 2 Yes
5 3 Yes
6 3 Stop
7 3 Yes
这是按ID排序的,每个ID至少有一个“停止”值,但可能没有“是”值。
我的目标是在每个Id上将所有值“ Stop”后的行“ Yes”排在同一Id上,但保留前一个和Stop,因此结果应为:
Id Val
0 1 Yes
1 1 Stop
4 2 Yes
5 3 Yes
6 3 Stop
如前所述,我有更多列要保留的信息,因此groupby并不是一种选择。实现此目的的最有效方法是什么?提前致谢
PD:对不起,如果有语法错误,英语不是我的母语。
一个想法是将每个组的索引值与值的第一个进行比较index
,Stop
并通过boolean indexing
以下方式进行过滤:
f = lambda x: x.index <= x.eq('Stop').idxmax()
mask = df.groupby('Id')['Val'].transform(f)
df = df[mask]
print (df)
Id Val
0 1 Yes
1 1 Stop
4 2 Yes
5 3 Yes
6 3 Stop
或可以使用GroupBy.cumsum
,但也有必要为选择Stop
行而转移:
mask = (df['Val'].eq('Stop').groupby(df['Id'])
.apply(lambda x: x.shift().cumsum())
.fillna(0)
.eq(0))
df = df[mask]
print (df)
Id Val
0 1 Yes
1 1 Stop
4 2 Yes
5 3 Yes
6 3 Stop
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句