Python-每个日期和月份PANDAS的所有非零列的计数

时间:2019-02-04 12:14:00

标签: python pandas dataframe

我有这个数据框,我希望每个月,日期和电子邮件中所有非零值的交互计数

    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

预先感谢

2 个答案:

答案 0 :(得分:2)

groupbyaggnumpy.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