Python 找出数据帧中事件的中间出现的“0”和第一出现的“1”
您好,我有一个pandas数据框,它有事件列和其他列。我想在id上执行group by,在group by上我想从所有连续0中提取2条记录我想找出连续5 0的模式可能更多,但它也必须始终后跟1,然后确定一组记录,即连续5 0的一个d后跟下一个1,然后从这5组0的记录中获取0的中间行,找出0之后的第一个1并获取该行。但对于0,我应该重复5次或更多次,然后从最后5个记录中获取中间行 简言之: 我想要0和1的集合,条件是只取1,对于上面找到的继续5 0或更多,如果此模式是多次的,则取一个模式为每个id获取两条记录,每个id具有0和1 例如Python 找出数据帧中事件的中间出现的“0”和第一出现的“1”,python,pandas,dataframe,Python,Pandas,Dataframe,您好,我有一个pandas数据框,它有事件列和其他列。我想在id上执行group by,在group by上我想从所有连续0中提取2条记录我想找出连续5 0的模式可能更多,但它也必须始终后跟1,然后确定一组记录,即连续5 0的一个d后跟下一个1,然后从这5组0的记录中获取0的中间行,找出0之后的第一个1并获取该行。但对于0,我应该重复5次或更多次,然后从最后5个记录中获取中间行 简言之: 我想要0和1的集合,条件是只取1,对于上面找到的继续5 0或更多,如果此模式是多次的,则取一个模式为每个id
import pandas as pd
data={'id':[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
'name': ['a','b','c','d','e','f','g','h','i','j','k','l','m','n'
,'o','p','q','r','s','t','a1','b1','c1','d1','e1','f1','g1','h1','i1','j1','k1','l1','m1','n1'
,'o1','p1','q1','r1','s1','t1','aa','bb','cc','dd','ee','ff',
'gg','hh','ii','jj','kk','ll','mm','nn'
,'oo','pp','qq','rr','ss','tt','aa1','bb1','cc1','dd1','ee1','ff1',
'gg1','hh1','ii1','jj1','kk1','ll1','mm1','nn1'
,'oo1','pp1','qq1','rr1','ss1','tt1'],
'value':[0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]}
df=pd.DataFrame.from_dict(data)
作为输出,我希望每个id获得2条记录,一条为0,一条为1。0行应该是5个或更多连续0的中间记录
预期产出为:
id name value
16 1 q 0
19 1 t 1
64 2 ee1 0
67 2 hh1 1
您可以使用透视表并为不同的值应用掩码来完成此操作。首先,我们应该按id、值对进行分组: 然后选择每个值的零==0和id对,并保留中间值:
mask_zeros = ((df_grouped['value']==0)*
(df_grouped['name'].apply(len)>=5))
df_zeros = mask_zeros*df_grouped['name'].apply(
lambda x: x[int(np.ceil(.5*len(x)))]
if len(x)%2==1
else x[int(.5*len(x))])
print(df_zeros)
0 f
1
2 o
3
并选择每个值==1和id对的第一个名称:
然后,通过指定以下项仅保留选定的名称:
df_grouped['name'] = df_ones + df_zeros
df_grouped = df_grouped.merge(df.reset_index(),
on=['name','value','id']
).set_index('index')
print(df_grouped)
id value name
index
5 1 0 f
2 1 1 c
14 2 0 o
10 2 1 k
我打破了台阶
df['New']=df.value.diff().fillna(0).ne(0).cumsum()
df1=df.loc[df.value.eq(0)]
s1=df1.groupby(['id','New']).filter(lambda x : len(x)>=5 ).groupby('id').apply(lambda x : x.iloc[len(x)//2-1:len(x)//2+1] if len(x)%2==0 else x.iloc[[(len(x)+1)//2],:] ).reset_index(level=0,drop=True)
s2=df1.groupby(['id','New']).filter(lambda x : len(x)>=5 )
pd.concat([df.loc[s2.drop_duplicates(['id'],keep='last').index+1],s1]).sort_index()
Out[1995]:
id name value New
5 1 f 0 2
6 1 g 0 2
9 1 j 1 3
14 2 o 0 4
16 2 q 1 5
谢谢Mabel,但我只需要4条记录作为输出,就这样。我不明白你的答案对我有什么帮助?好的,我知道了。如果有奇数个0,两个相邻的中间元素和第一个1,你想返回中间元素吗?是的,只需要一个小的更改,我不需要两个相邻的0,只有一个就可以了。实际上,我似乎尚未涵盖我的数据集的所有场景。我不是在寻找索引+1的下一个立即数,但我在寻找0之后出现的1,现在1可以是下一个立即数索引,也可以是多个0之后。因此,我需要我们确定的0之后的任何第一个1?对此有何建议?另一个问题是,在我的数据集中它的发生就像我得到了相当多的0的数量,比如20-25个计数,然后得到1,那么是否有可能得到最后5个连续的0,并将中间部分作为0的一个记录,并将下一个1作为1的另一个记录?我的数据是每个月的事件,所以在目前的情况下,我从2014年得到0,从2017年得到1,这是什么时间窗很大。我希望我有点清楚?如果你的问题解决了,请用绿色勾号标出正确答案,这样线程就关闭了。
df_grouped['name'] = df_ones + df_zeros
df_grouped = df_grouped.merge(df.reset_index(),
on=['name','value','id']
).set_index('index')
print(df_grouped)
id value name
index
5 1 0 f
2 1 1 c
14 2 0 o
10 2 1 k
df['New']=df.value.diff().fillna(0).ne(0).cumsum()
df1=df.loc[df.value.eq(0)]
s1=df1.groupby(['id','New']).filter(lambda x : len(x)>=5 ).groupby('id').apply(lambda x : x.iloc[len(x)//2-1:len(x)//2+1] if len(x)%2==0 else x.iloc[[(len(x)+1)//2],:] ).reset_index(level=0,drop=True)
s2=df1.groupby(['id','New']).filter(lambda x : len(x)>=5 )
pd.concat([df.loc[s2.drop_duplicates(['id'],keep='last').index+1],s1]).sort_index()
Out[1995]:
id name value New
5 1 f 0 2
6 1 g 0 2
9 1 j 1 3
14 2 o 0 4
16 2 q 1 5