计算大熊猫的条纹而不适用

时间:2019-10-08 02:12:17

标签: python pandas apply

我有一个这样的DataFrame:

date       | type | column1
----------------------------
2019-01-01 |   A  |    1
2019-02-01 |   A  |    1
2019-03-01 |   A  |    1
2019-04-01 |   A  |    0
2019-05-01 |   A  |    1
2019-06-01 |   A  |    1
2019-07-01 |   B  |    1
2019-08-01 |   B  |    1
2019-09-01 |   B  |    0

我想要一个名为“ streak”的列,该列具有条纹,但按列“ type”分组:

date       | type | column1 | streak
-------------------------------------
2019-01-01 |   A  |    1    |   1
2019-02-01 |   A  |    1    |   2
2019-03-01 |   A  |    1    |   3
2019-04-01 |   A  |    0    |   0
2019-05-01 |   A  |    1    |   1
2019-06-01 |   A  |    1    |   2
2019-07-01 |   B  |    1    |   1
2019-08-01 |   B  |    1    |   2
2019-09-01 |   B  |    0    |   0

我设法做到了:

def streak(df):
    grouper = (df.column1 != df.column1.shift(1)).cumsum()
    df['streak'] = df.groupby(grouper).cumsum()['column1']
    return df

df = df.groupby(['type']).apply(streak)

但是我想知道是否可以不使用groupby并应用而直接进行内联,因为我的DataFrame包含大约1亿行,并且要花几个小时才能处理。

关于如何优化速度的任何想法?

2 个答案:

答案 0 :(得分:4)

您希望按cumsum分组的'column1'中的'type' +布尔系列的cumsum,该布尔序列每0重置一次分组。

df['streak'] = df.groupby(['type', df.column1.eq(0).cumsum()]).column1.cumsum()

         date type  column1  streak
0  2019-01-01    A        1       1
1  2019-02-01    A        1       2
2  2019-03-01    A        1       3
3  2019-04-01    A        0       0
4  2019-05-01    A        1       1
5  2019-06-01    A        1       2
6  2019-07-01    B        1       1
7  2019-08-01    B        1       2
8  2019-09-01    B        0       0

答案 1 :(得分:4)

IIUC,这就是您所需要的。

m = df.column1.ne(df.column1.shift()).cumsum()
df['streak'] =df.groupby([m , 'type'])['column1'].cumsum()

输出

       date     type    column1     streak  
0   1/1/2019    A             1     1   
1   2/1/2019    A             1     2   
2   3/1/2019    A             1     3   
3   4/1/2019    A             0     0   
4   5/1/2019    A             1     1   
5   6/1/2019    A             1     2   
6   7/1/2019    B             1     1   
7   8/1/2019    B             1     2   
8   9/1/2019    B             0     0