Python 如何根据5天/idx规则优雅地删除列中的值?
我有一个如下所示的数据帧Python 如何根据5天/idx规则优雅地删除列中的值?,python,python-3.x,pandas,dataframe,pandas-groupby,Python,Python 3.x,Pandas,Dataframe,Pandas Groupby,我有一个如下所示的数据帧 test1 = pd.DataFrame({ 'subject_id':[1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2], 'flag' : ['','','T1','T1','T1','T1','T1','T1','T1','T1','','','T1','T1','T1','T1','T1','T1','T1','T1'] }) 如下图所示 根据规则/逻辑,T1只能在其第一次出现的5天/记录之后出现在标志字
test1 = pd.DataFrame({
'subject_id':[1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2],
'flag' : ['','','T1','T1','T1','T1','T1','T1','T1','T1','','','T1','T1','T1','T1','T1','T1','T1','T1']
})
如下图所示
根据规则/逻辑,T1
只能在其第一次出现的5天/记录之后出现在标志字段中。例如,如果T1
发生在3rd
索引上,那么它只能发生在9th
索引和更多索引上。之前的任何内容都无效,必须删除
我试过下面的方法。虽然这是可行的,但它看起来并不优雅,也不适合所有科目
a = test1[test1['flag']=='T1'].index.min()
test1.loc[a+1:a+6, 'flag'] = ''
我如何为所有受试者单独进行检查?每个主题及其标志都应遵循此规则
我希望我的输出如下所示。您可以看到无效标志被删除
我们可以做
s=test1['flag'].eq('T1').groupby(test1['subject_id']).transform('idxmax')
test1.loc[~((test1.index==s)|(test1.index>(s+5))),'flag']=''
我们能做到
s=test1['flag'].eq('T1').groupby(test1['subject_id']).transform('idxmax')
test1.loc[~((test1.index==s)|(test1.index>(s+5))),'flag']=''
这里是一种稍微不同的方法,在一个管道语句中。为了清楚起见,我正在为cumsum和条件创建额外的列,然后对数据帧进行子设置
test1.\
assign(cum_sum=lambda x: x.flag.eq('T1').groupby(x.subject_id).cumsum()).\
assign(condition=lambda x: (x.flag=='') | (x.cum_sum==1) | (x.cum_sum >=5)).\
loc[lambda x: x.condition]
希望这能有所帮助。这里有一个稍微不同的方法,在一个管道语句中。为了清楚起见,我正在为cumsum和条件创建额外的列,然后对数据帧进行子设置
test1.\
assign(cum_sum=lambda x: x.flag.eq('T1').groupby(x.subject_id).cumsum()).\
assign(condition=lambda x: (x.flag=='') | (x.cum_sum==1) | (x.cum_sum >=5)).\
loc[lambda x: x.condition]
希望这有帮助。下面的两个答案都很好。然而,我只能将一个答案标记为解决方案。因此我使用@WeNYoBen,因为它很短。尽管如此,这两个答案都提供了预期的输出,并且都是向上的。下面的两个答案都是好的。然而,我只能将一个答案标记为解决方案。因此我使用@WeNYoBen,因为它很短。尽管如此,这两个答案都提供了预期的结果,而且都是经过投票的