在熊猫中表演类似excel的countifs

时间:2016-12-29 09:57:20

标签: python excel pandas countif

我有一个数据集,列出了完成某些操作的员工和时间戳。它分为三列:员工,日期,小时。

我想计算每小时活跃的员工人数。在excel中,我会通过添加第四列EmpFactor来执行此操作,其中我执行COUNTIFS操作:

=1/COUNTIFS(Name range;Name;Date range;Date;Hour range;Hour)

我随后可以通过在SUMIF列上执行EmpFactor来计算有效员工的数量。

我尝试使用以下代码使用pandas组成EmpFactor列:

for name,date,time in zip(df['Employee'],df['Date'],df['Time']):
    df['EmpFactor'] = 1/(df[(df.Employee == name) and (df.Day == dag) 
                             and (df.Time == tijd)].count())
然而,这并不起作用。我已经广泛搜索了很多关于SO的主题,但尚未找到合适的答案。

2 个答案:

答案 0 :(得分:1)

从这个数据框开始:

df = pd.DataFrame({'Employee': list('ABCDEFGH'), 
                   'Date': [1, 1, 1, 2, 2, 2, 3, 3],
                   'Time': [10, 10, 10, 11, 10, 11, 11, 12]})
print(df)

输出:

   Date Employee  Time
0     1        A    10
1     1        B    10
2     1        C    10
3     2        D    11
4     2        E    10
5     2        F    11
6     3        G    11
7     3        H    12

您可以按DateTime分组并计算员工数:

per_hour = df.groupby(['Date', 'Time']).count()
per_hour['EmpFactor'] = 1 / per_hour.Employee
print(per_hour)

输出:

           Employee  EmpFactor
Date Time                     
1    10           3   0.333333
2    10           1   1.000000
     11           2   0.500000
3    11           1   1.000000
     12           1   1.000000

答案 1 :(得分:1)

假设您有这样的DataFrame结构:

import pandas as pd
import numpy as np
df = pd.DataFrame([['Alice', '2012-03-05', 23], 
                   ['Fred',  '2012-03-05', 23], 
                   ['Bob',   '2012-12-12', 00]], 
                  columns=('Employee', 'Date', 'Time'))

# Here you have:
    Employee        Date  Time
0      Alice  2012-03-05    23
1       Fred  2012-03-05    23
2        Bob  2012-12-12     0

# convert to a date
df['DateTime']=pd.to_datetime(df['Date'])
# make it index
df2=df.set_index('DateTime')
# group by date and time
g = df2.groupby([pd.TimeGrouper('D'), 'Time'])
# get counts:
print(g.count())

#Here you have:
                     Employee  Date
DateTime      Time
2012-03-05     23           2     2
2012-12-12      0           1     1


# to get inverted values:
print(1/g.count())

                   Employee  Date
DateTime     Time
2012-03-05   23         0.5   0.5
2012-12-12   0          1.0   1.0

当然,最好将Time列作为DateTime列的一部分。如果你愿意,你可以练习:)

这种方法非常快:在笔记本电脑上分组47M行需要大约3分钟。