我有一个这样的数据框:
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开始计数。
任何想法/建议?感谢。
答案 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