我有这个数据框,我希望每个月,日期和电子邮件中所有非零值的交互计数
DATE LOC EMAIL INTERATION
1/11 INDIA qw@mail.com 0
1/11 INDIA ap@mail.com 11
1/11 LONDON az@mail.com 2
2/11 INDIA qw@mail.com 5
2/11 INDIA rw@mail.com 5
2/11 LONDON az@mail.com 0
3/11 LONDON az@mail.com 1
因此,我得到的数据框应如下所示:
DATE LOC INTERATION
1/11 INDIA 1
1/11 LONDON 1
2/11 INDIA 2
2/11 LONDON 0
3/11 LONDON 1
预先感谢
答案 0 :(得分:2)
将groupby
与agg
和numpy.count_nonzero
结合使用:
df1 = df.groupby(['DATE','LOC'], as_index=False)['INTERATION'].agg(np.count_nonzero)
print (df1)
DATE LOC INTERATION
0 1/11 INDIA 1
1 1/11 LONDON 1
2 2/11 INDIA 2
3 2/11 LONDON 0
4 3/11 LONDON 1
另一种解决方案是通过不等于ne
的方式创建布尔掩码,将其转换为整数并聚合sum
:
df1 = (df.assign(INTERATION = df['INTERATION'].ne(0).astype(int))
.groupby(['DATE','LOC'], as_index=False)['INTERATION']
.sum())
如果也需要按列EMAIL
进行分组:
df2 = df.groupby(['DATE','LOC','EMAIL'], as_index=False)['INTERATION'].agg(np.count_nonzero)
print (df2)
DATE LOC EMAIL INTERATION
0 1/11 INDIA ap@mail.com 1
1 1/11 INDIA qw@mail.com 0
2 1/11 LONDON az@mail.com 1
3 2/11 INDIA qw@mail.com 1
4 2/11 INDIA rw@mail.com 1
5 2/11 LONDON az@mail.com 0
6 3/11 LONDON az@mail.com 1
答案 1 :(得分:1)
一个不一定有效的解决方案是先转换为bool
,然后转换为sum
。在计算中,使用0
/ 1
分别等于False
/ True
这一事实:
res = df.groupby(['DATE', 'LOC'])['INTERATION']\
.apply(lambda x: x.astype(bool).sum()).reset_index()
print(res)
DATE LOC INTERATION
0 1/11 INDIA 1
1 1/11 LONDON 1
2 2/11 INDIA 2
3 2/11 LONDON 0
4 3/11 LONDON 1