Pandas连续数累计和

2024-06-11 15:36:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个数据帧:

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

我想得到这个:

^{pr2}$

基本上我想得到连续的1的累计和,如果名字改变或者有0,它应该从0开始计数。在

有什么想法/建议吗?谢谢。在


Tags: 数据name名字建议计数date1pr2date2
3条回答

以下是一个无需显式循环的矢量化解决方案:

df = pd.DataFrame.from_dict({'name': list('AAAAABBBB'), 'bit': (1,0,1,1,1,1,1,0,1)})
>>> df
   bit name
0    1    A
1    0    A
2    1    A
3    1    A
4    1    A
5    1    B
6    1    B
7    0    B
8    1    B
>>> reset = (df['bit'] == 0) | (df['name'] != df['name'].shift(1))
>>> reset, = np.where(np.concatenate([reset, [True]]))
>>> df['count'] = np.arange(reset[-1]) + (df['bit'].values[reset[:-1]]-reset[:-1]).repeat(np.diff(reset))
>>> df
   bit name  count
0    1    A      1
1    0    A      0
2    1    A      1
3    1    A      2
4    1    A      3
5    1    B      1
6    1    B      2
7    0    B      0
8    1    B      1

以下是我自己的看法:

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)每当一个值与前面的值不同时,df[2].diff().ne(0)会给我们一个真值,而这些值的累计和在新的1组开始时给我们一个新的数字。在

当然,这意味着对于跨越不同名称的二进制值,我们有相同的group_id,但是由于我们是根据两个df[0](名称)和group_id分组的,所以我们没问题。在

我像这样重建了你的数据:

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,这样我可以显式地声明您指定的两个条件(name change和value列中的0):

^{pr2}$

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

^{3}$

结果:

    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.groupbyhere的说明。在

相关问题 更多 >