这是我的代码:
df1 = pd.DataFrame({'a': [1,2,3,1,2,3,3],'b':[1,2,3,1,2,3,3],'type':[1,0,1,0,1,0,1]})
def add_buy_label(group):
behavior_type = group.type.astype(int)
if 1 in group['type']:
group['buy_label'] = 1
else:
group['buy_label'] = 0
return group[['a', 'b', 'type','buy_label']]
上面的功能是只要组中存在一个(类型= 1),就将所有a-b项的buy_label设置为1,但是,之后的结果
df1.groupby(['a','b'],as_index = False).apply(add_buy_label)
是
a b type buy_label
0 1 1 1 0
1 2 2 0 1
2 3 3 1 0
3 1 1 0 0
4 2 2 1 1
5 3 3 0 0
6 3 3 1 0
很明显,具有3的行是错误的,因为在(a = 3,b = 3)的组中存在type = 1,但是相应的buy_label为0。
我该如何解决?
答案 0 :(得分:1)
存在问题in
,而不是列值。
#sorting for better seen groups
df1 = df1.sort_values(['a','b'])
df2 = df1.groupby(['a','b'],as_index = False).apply(add_buy_label)
print (df2)
a b type buy_label
0 1 1 1 0
3 1 1 0 0
1 2 2 0 1 <- return 1 only because index == 1 per group (2,2)
4 2 2 1 1
2 3 3 1 0
5 3 3 0 0
6 3 3 1 0
因此需要1
和any
的比较来检查至少一个True
:
if group['type'].eq(1).any():
#what is same as
if (group['type'] == 1).any():
答案 1 :(得分:1)
如前所述,带有系列的in
检查系列索引而不是系列值的成员资格。像Python dict
这样的系列,您将看到这种处理方式是如何一致的:for k in my_dict
检查字典键中的成员资格。
表达逻辑的另一种方法是将groupby
+ transform
与unique
一起使用:
df1['buy_label'] = df1.groupby(['a', 'b'])['type']\
.transform('unique')\
.apply(lambda x: 1 in x)\
.astype(int)