Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何根据5天/idx规则优雅地删除列中的值?_Python_Python 3.x_Pandas_Dataframe_Pandas Groupby - Fatal编程技术网

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,因为它很短。尽管如此,这两个答案都提供了预期的结果,而且都是经过投票的