熊猫 - 连续的累计和

时间:2018-05-19 22:45:59

标签: python pandas group-by cumulative-sum

我有一个这样的数据框:

Name_A ¦  date1 ¦ 1

Name_A ¦  date2 ¦ 0 

Name_A ¦  date3 ¦ 1

Name_A ¦  date4 ¦ 1

Name_A ¦  date5 ¦ 1

Name_B ¦  date6 ¦ 1

Name_B ¦  date7 ¦ 1

Name_B ¦  date8 ¦ 0

Name_B ¦  date9 ¦ 1

我想得到这个:

Name_A ¦ date1 ¦ 1  

Name_A ¦ date2 ¦ 0  

Name_A ¦ date3 ¦ 1  

Name_A ¦ date4 ¦ 2 

Name_A ¦ date5 ¦ 3

Name_B ¦ date6 ¦ 1

Name_B ¦ date7 ¦ 2

Name_B ¦ date8 ¦ 0

Name_B ¦ date9 ¦ 1 

基本上我想得到连续1的累积和。如果名称改变或者为0,则应该从0开始计数。

任何想法/建议?感谢。

3 个答案:

答案 0 :(得分:2)

这是我自己的看法:

In [145]: group_ids = df[2].diff().ne(0).cumsum()

In [146]: df["count"] = df[2].groupby([df[0], group_ids]).cumsum()

In [147]: df
Out[147]: 
        0      1  2  count
0  Name_A  date1  1      1
1  Name_A  date2  0      0
2  Name_A  date3  1      1
3  Name_A  date4  1      2
4  Name_A  date5  1      3
5  Name_B  date6  1      1
6  Name_B  date7  1      2
7  Name_B  date8  0      0
8  Name_B  date9  1      1

这使用了compare-cumsum-groupby模式来查找连续的组,因为只要值与前一个值不同,df[2].diff().ne(0)就会给出一个True,并且这些值的累积总和给我们一个新的每当新的1组开始时编号。

这意味着我们对于跨越不同名称的二进制值具有相同的group_id,当然,但由于我们将分组 df [0](名称)和group_ids,我们'好的。

答案 1 :(得分:0)

我重建了你的数据:

import pandas as pd

df = pd.DataFrame(
    {'col1': ['Name_A'] * 5 + ['Name_B'] * 4,
     'col2': ['date{}'.format(x) for x in list(range(1,10,1))],
     'col3': [1,0,1,1,1,1,1,0,1]})

对于您建议的分组类型,我喜欢使用itertools.groupby而不是pd.groupby,这样我就可以明确说明您指定的两个条件(名称更改和值列中的0) :

from itertools import groupby

groups = []
uniquekeys = []
for k, g in groupby(df.iterrows(), 
                    lambda row: (row[1]['col1'], row[1]['col3'] == 0)):
    groups.append(list(g))
    uniquekeys.append(k)

现在存在正确的组,剩下的就是迭代然后计算累积和:

cumsum = pd.concat([pd.Series([y[1]['col3'] for y in x]).cumsum() for x in groups])

df['cumsum'] = list(cumsum)

结果:

    col1    col2    col3    cumsum
0   Name_A  date1   1       1
1   Name_A  date2   0       0
2   Name_A  date3   1       1
3   Name_A  date4   1       2
4   Name_A  date5   1       3
5   Name_B  date6   1       1
6   Name_B  date7   1       2
7   Name_B  date8   0       0
8   Name_B  date9   1       1

供参考,请参阅有关itertools.groupby here的详细说明。

答案 2 :(得分:0)

这是一个不需要显式循环的矢量化解决方案:

requiresDependencyResolution = ResolutionScope.TEST