2016-12-29 8 views
1

У меня есть набор данных, в котором перечислены сотрудники и временные метки, на которых они выполняют определенные действия. Он разделен на три столбца: Employee, Date, Hour.Выполнение великолепных счетчиков в Pandas

Я хочу подсчитать количество сотрудников, которые активны каждый час. В Excel Я хотел бы сделать это, добавив четвертый столбец EmpFactor, в котором я выполнить операцию: COUNTIFS

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

можно затем вычислить количество активных сотрудников, выполняя SUMIF на EmpFactor колонке.

Я попытался следующий код, чтобы составить 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

Будет полезно иметь выборочные данные и ожидаемый результат. – Zero

+0

Это может быть не изящно, но его начало, если вы просто перебираете свой массив и + = счетчику для совпадений, тогда выполните свою инверсию. –

+0

Спасибо! Я выбрал последний подход, который, похоже, работает. – TimH

ответ

1

Начиная с этого dataframe:

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 

Вы можете сгруппировать по Date и Time и сосчитать сотрудников:

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

Предположим, у вас есть такая структура 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 колонны. Вы можете попрактиковаться в этом, если хотите.

Этот подход довольно быстрый: потребовалось около 3 минут для группировки 47M строк на моем ноутбуке.

 Смежные вопросы

  • Нет связанных вопросов^_^