2016-12-29 3 views
1

Ich habe eine Datenmenge, die Mitarbeiter und Zeitstempel auf denen sie bestimmte Aktionen abgeschlossen sind. Es ist in drei Spalten unterteilt: Mitarbeiter, Datum, Stunde.Durchführen eines Excel-like Countifs in Pandas

Ich möchte die Anzahl der Mitarbeiter, die jede Stunde aktiv ist, zählen. In Excel würde ich dies tun, indem eine vierte Spalte EmpFactor, in dem das Hinzufügen führe ich einen COUNTIFS Betrieb:

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

Ich kann anschließend die Anzahl der aktiven Mitarbeiter berechnen, indem ein SUMIF auf der EmpFactor Spalte durchgeführt wird.

Ich habe versucht, den folgenden Code die EmpFactor Spalte Pandas zu komponieren:

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()) 

Dies ist jedoch nicht funktioniert. Ich habe ausgiebig durch zahlreiche Themen zu SO gesucht, aber noch keine passende Antwort gefunden.

+2

Es wird hilfreich sein, Beispieldaten und die erwartete Ausgabe zu haben. – Zero

+0

Es ist vielleicht nicht elegant, aber es ist ein Start, wenn Sie einfach Ihr Array und + = zu einem Zähler für Matches iterieren, dann machen Sie Ihre Inversion. –

+0

Danke! Ich habe den letzteren Ansatz gewählt, der zu funktionieren scheint. – TimH

Antwort

1

mit diesem Datenrahmen Ab:

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) 

Ausgang:

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 

Sie können Gruppe von Date und Time und den Mitarbeitern zählen:

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

Ausgang:

  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

Angenommen, Sie solche Struktur von Datenrahmen haben:

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 

Natürlich besser machen Time Teil der DateTime Spalte. Sie können üben, wenn Sie es wünschen :)

Dieser Ansatz ist ziemlich schnell: Es dauerte etwa 3 Minuten für die Gruppierung 47M Zeilen auf meinem Laptop.