如何根据停止条件对已排序的DataFrame进行分组?

时间:2016-05-18 14:32:40

标签: python pandas

假设我下面的pandas DataFrame已经在A列上排序。

import pandas as pd
data = {'A': range(15),
        'B': range(5)*3}
df = pd.DataFrame(data)
# just in case:
df.sort('A', inplace=True)

结果数据框看起来像这样:

A  | B
-----
0  | 0
1  | 1
2  | 2
3  | 3
4  | 4
5  | 0
6  | 1
7  | 2
8  | 3
9  | 4
10 | 0
11 | 1
12 | 2
13 | 3
14 | 4

我想根据B列中的“停止点”将其分为三组,其中该列的值从4减少到0.对于groupby的天真使用无法适应这一点,因为没有关键区分群体。

通过按排序顺序迭代各个行来做到这一点很简单,但我想知道是否有一个pandas-native解决方案。

1 个答案:

答案 0 :(得分:2)

IIUC您可以为cumsum

为groupby创建新列C
df['C'] = ((df.B == 0).cumsum())

print (df)
     A  B  C
0    0  0  1
1    1  1  1
2    2  2  1
3    3  3  1
4    4  4  1
5    5  0  2
6    6  1  2
7    7  2  2
8    8  3  2
9    9  4  2
10  10  0  3
11  11  1  3
12  12  2  3
13  13  3  3
14  14  4  3

print (df.groupby('C').sum())
    A   B
C        
1  10  10
2  35  10
3  60  10

或更好groupby Series

print (df[['A','B']].groupby([((df.B == 0).cumsum())]).sum())
    A   B
B        
1  10  10
2  35  10
3  60  10

对于存储组,可以使用dict理解:

for i, g in df[['A','B']].groupby([((df.B == 0).cumsum())]):
    print (i)
    print (g)    

1
   A  B
0  0  0
1  1  1
2  2  2
3  3  3
4  4  4
2
   A  B
5  5  0
6  6  1
7  7  2
8  8  3
9  9  4
3
     A  B
10  10  0
11  11  1
12  12  2
13  13  3
14  14  4

dfs = {i-1: g for i,g in df[['A','B']].groupby([((df.B == 0).cumsum())])}
print (dfs[0])
   A  B
0  0  0
1  1  1
2  2  2
3  3  3
4  4  4