根据列值将 pandas 数据框分成“块”

cmj*_*607 5 python pandas

解释我想要完成的任务的最好方法可能只是一个例子。给定以下数据帧:

     tag  ID
0     0   1
1     0   2
2     1   3
3     1   4
4     0   5
5     1   6
6     0   7
7     0   8
8     1   9
9     1  10
10    0  11
11    0  12
12    0  13
13    1  14
14    1  15
15    1  16
16    0  17 
Run Code Online (Sandbox Code Playgroud)

根据标签,将数据帧分成“块”。当一个块被识别时,它被存储在一个单独的数据帧中(或者可能是一个数据帧列表?)。“分块”的标准是在标签列中查找 2 个或更多零。如果有超过 2 个零,则删除前一个零和当前零之间存在的所有数据。

在上面的示例数据帧中,代码将删除索引的行:0,1,6,7,10,11,12...然后它将以下块存储到单独的数据帧中:

     tag  ID
2     1   3
3     1   4
4     0   5
5     1   6

     tag  ID
8     1   9
9     1  10

     tag  ID
13    1  14
14    1  15
15    1  16
16    0  17
Run Code Online (Sandbox Code Playgroud)

我希望它清楚。如果没有的话,抱歉……有没有一种很好的Pythonic方法来完成这个任务,而不会创建一大堆循环?

谢谢你的帮助,CJ

WeN*_*Ben 3

已经尽力了......我正在使用另外两个新参数

df['group']=df.tag.diff().fillna(0).ne(0).cumsum()
df1=df.groupby('group').tag.agg([sum,lambda x : len(x)])
dropindex=df1[(df1['sum']==0)&(df1['<lambda>']>1)].index # only drop more than one continue 0 
df=df.loc[~df.group.isin(dropindex)]
df['group2']=df.reset_index()['index'].diff().ne(1).cumsum().values
for _, dfyourneed in df.groupby('group2',as_index=False):
    print(dfyourneed.drop(['group2','group'],1))

   tag  ID
2    1   3
3    1   4
4    0   5
5    1   6
   tag  ID
8    1   9
9    1  10
    tag  ID
13    1  14
14    1  15
15    1  16
16    0  17
Run Code Online (Sandbox Code Playgroud)

或者您可以将其保存到列表中

[dfyourneed.drop(['group2', 'group'], 1) for _, dfyourneed in df.groupby('group2', as_index=False)]
Out[1083]: 
[   tag  ID
 2    1   3
 3    1   4
 4    0   5
 5    1   6,    tag  ID
 8    1   9
 9    1  10,     tag  ID
 13    1  14
 14    1  15
 15    1  16
 16    0  17]
Run Code Online (Sandbox Code Playgroud)