2016-10-13 226 views
2

我有這個結構的數據幀:熊貓GROUPBY COUNTIF

time,10.0.0.103,10.0.0.24 
2016-10-12 13:40:00,157,172 
2016-10-12 14:00:00,0,203 
2016-10-12 14:20:00,0,0 
2016-10-12 14:40:00,0,200 
2016-10-12 15:00:00,185,208 

它詳細介紹了每個IP地址的事件,對於一個給定20分鐘時期的數量。我需要一個關於每個礦工有多少20分鐘時間有0個事件的數據框,從這個數據框我需要以百分比的形式獲得IP'正常運行時間'。 IP地址的數量是動態的。所需的輸出:

IP,noEvents,uptime 
10.0.0.103,3,40 
10.0.0.24,1,80 

我試過用groupby,agg和lambda無濟於事。通過動態列進行「countif」的最佳方式是什麼?

+0

如果礦工IP'10.0.0.103'有3個階段(5個)沒有意外,他的正常運行時間不應該是60%嗎? – unutbu

+0

嗯,是的。我的錯。 – user6949779

回答

3

您可以通過條件df == 0使用布爾掩碼的summean。最後concat兩個Series

df.set_index('time', inplace=True) 
mask = (df == 0) 
print (mask) 
        10.0.0.103 10.0.0.24 
time          
2016-10-12 13:40:00  False  False 
2016-10-12 14:00:00  True  False 
2016-10-12 14:20:00  True  True 
2016-10-12 14:40:00  True  False 
2016-10-12 15:00:00  False  False 

noEvents = mask.sum() 
print (noEvents) 
10.0.0.103 3 
10.0.0.24  1 
dtype: int64 

uptime = 100 * mask.mean() 
print (uptime) 
10.0.0.103 60.0 
10.0.0.24  20.0 
dtype: float64 

print (pd.concat([noEvents, uptime], axis=1, keys=('noEvents','uptime')) 
     .reset_index() 
     .rename(columns={'index':'IP'})) 

      IP noEvents uptime 
0 10.0.0.103   3 60.0 
1 10.0.0.24   1 20.0 
2

移調DF

df = df.T 

既然你一起使用groupby的線試過了,你可以繼續進行使用value_counts拿到零的計數各組堆疊後它會產生一個series對象,並隨後將其拆回回DF,如下所示:

grp = df.stack().to_frame('val').groupby(level=0)['val'] 
df['noEvents'] = grp.value_counts().unstack()[0] 

後來劃分值與該組的規模來獲得它的百分比分佈:

df['upTime'] = (100*df['noEvents']/grp.size()) 

對於審美目的:

df = df[['noEvents', 'upTime']].astype(int) 
df.index.name = 'IP' 
df.columns.name = None 
df 

Image