2017-01-30 195 views
3

這個問題與my previous question。相關。我有以下數據框:如何將平均百分比和平均數的列添加到數據框?

df = 
    QUEUE_1 QUEUE_2 DAY HOUR TOTAL_SERVICE_TIME TOTAL_WAIT_TIME EVAL 
    ABC123 DEF656 1  7  20     30    1 
    ABC123    1  7  22     32    0 
    DEF656 ABC123 1  8  15     12    0 
    FED456 DEF656 2  8  15     16    1 

我需要得到以下數據框(這是一個類似於我想在我的前面的問題就搞定了,但是在這裏我需要添加2分額外的列AVG_COUNT_PER_DAY_HOURAVG_PERCENT_EVAL_1)。

QUEUE HOUR AVG_TOT_SERVICE_TIME AVG_TOT_WAIT_TIME AVG_COUNT_PER_DAY_HOUR AVG_PERCENT_EVAL_1 
ABC123 7  21     31     1      50 
ABC123 8  15     12     0.5      100 
DEF656 7  20     30     0.5      100 
DEF656 8  15     14     1      50 
FED456 7  0      0     0      0 
FED456 8  15     14     0.5      100 

AVG_COUNT_PER_DAY_HOUR應包含對應HOUR值隨天QUEUE分組的平均計數(DAY)。例如,在df中,在ABC123的情況下,HOUR 7對於DAY出現2次並且對於DAY 2出現0次。因此,平均值爲1.相同的邏輯適用於HOUR8。它出現1次DAY 1和0次ABC123。因此平均值爲0.5。

AVG_PERCENT_EVAL_1應包含EVAL的百分比等於1小時,按QUEUE分組。例如,在ABC123情況下,EVAL等於1週一次時HOUR是7。它也等於0一個時間時HOUR是7。所以,AVG_PERCENT_EVAL_1是50 ABC123和小時7.

我使用這種方法:

df = pd.lreshape(aa, {'QUEUE': df.columns[df.columns.str.startswith('QUEUE')].tolist()}) 
piv_df = df.pivot_table(index=['QUEUE'], columns=['HOUR'], fill_value=0) 
result = piv_df.stack().add_prefix('AVG_').reset_index() 

我卡住與添加列AVG_COUNT_PER_DAY_HOURAVG_PERCENT_EVAL_1。例如,要添加列AVG_COUNT_PER_DAY_HOUR我想用.apply(pd.value_counts, 1).notnull().groupby(level=0).sum().astype(int),而計算AVG_PERCENT_EVAL_1我想用[df.EVAL==1].agg({'EVAL' : 'count'})。但是,不知道如何將它合併到我的當前代碼中以獲得正確的解決方案。

UPDATE:

也許更容易採用這種解決方案,我需要在這個問題:

result = pd.lreshape(df, {'QUEUE': ['QUEUE_1','QUEUE_2']}) 

mux = pd.MultiIndex.from_product([result.QUEUE.dropna().unique(), 
            result.dropna().DAY.unique(), 
            result.HOUR.dropna().unique(), ], names=['QUEUE','DAY','HOUR']) 

print (result.groupby(['QUEUE','DAY','HOUR']) 
      .mean() 
      .reindex(mux, fill_value=0) 
      .add_prefix('AVG_') 
      .reset_index()) 

回答

3

步驟:

1)來計算AVG_COUNT_PER_DAY_HOUR

隨着pd.crosstab()的幫助下,計算不同數HOUR的w.r.t(讓我們得到了失蹤天的情況下)由隊列分組。

stackDF使HOUR這是一個分層列的部分之前現在被定位爲一個指數,只留下爲列。填充NaNs後,我們採用平均列方式。

2)來計算AVG_PERCENT_EVAL_1

得到的樞軸轉動架(同前)之後,也從意味着將只給我們的百分比變化爲那些在本質上只是二進制的事實(1/0),我們只需從DF中取EVAL,並將其結果乘以100,因爲它們是在自行轉動時計算的(默認agg = np.mean)。

最後,我們加入所有這些框架。


相同鏈接的交:

df = pd.lreshape(df, {'QUEUE': df.columns[df.columns.str.startswith('QUEUE')].tolist()}) 
piv_df = df.pivot_table(index='QUEUE', columns='HOUR', fill_value=0).stack() 
avg_tot = piv_df[['TOTAL_SERVICE_TIME', 'TOTAL_WAIT_TIME']].add_prefix("AVG_") 

附加部分:

avg_cnt = pd.crosstab(df['QUEUE'], [df['DAY'], df['HOUR']]).stack().fillna(0).mean(1) 
avg_pct = piv_df['EVAL'].mul(100).astype(int) 
avg_tot.join(
    avg_cnt.to_frame("AVG_COUNT_PER_DAY_HOUR") 
).join(avg_pct.to_frame("AVG_PERCENT_EVAL_1")).reset_index() 

enter image description here


avg_cnt樣子:

QUEUE HOUR 
ABC123 7  1.0 
     8  0.5 
DEF656 7  0.5 
     8  1.0 
FED456 7  0.0 
     8  0.5 
dtype: float64 

avg_pct樣子:

QUEUE HOUR 
ABC123 7  50 
     8   0 
DEF656 7  100 
     8  50 
FED456 7   0 
     8  100 
Name: EVAL, dtype: int32 
+1

謝謝。我可以請你簡單介紹一下你的代碼嗎? – Dinosaurius

+0

我是否正確理解在'pd.crosstab'之前我應該​​運行'df = pd.lreshape(df,{'QUEUE':df.columns [df.columns.str.startswith('QUEUE')]。tolist() })? – Dinosaurius

+0

還有一條評論。當我運行從前一個線程(由您提出的線程)獲取的原始代碼時,我會得到不同的AVG_TOTAL_SERVICE_TIME和AVG_TOTAL_WAIT_TIME值,但它們必須相同。我引用這個代碼:'df = pd.lreshape(aa,{'QUEUE':df.columns [df.columns.str.startswith('QUEUE')]。tolist()}) piv_df = df.pivot_table( index = ['QUEUE'],columns = ['HOUR'],fill_value = 0) result = piv_df.stack().add_prefix('AVG_').setup_index()'。 – Dinosaurius