2017-08-31 116 views
2

我處理的一個熊貓數據幀像這樣的:提取新列與數出熊貓的數據幀GROUPBY的

 Day Hour   Prio Value 
0  1  6  Critical  1 
1  1 16  Critical  1 
2  1 17  Content  1 
3  1 17   Low  1 
6  1 19  Critical  1 
7  1 20   High  1 
8  2 10   High  1 
9  2 10   Low  2 

,現在我想希望通過日和小時組,而產生代表計數新列列Prio中的每個值中的每個值,其當前存在於列value中。所以我想達到這樣的結構:

 Day Hour Critical Content Low High 
0  1  6   1  0 0  0 
1  1 16   1  0 0  0 
2  1 17   0  1 1  0 
6  1 19   1  0 0  0 
7  1 20   0  0 0  1 
8  2 10   0  0 2  1 

我現在嘗試了不同的事情,但一直都不是很成功。我的目標是將這個數據框與Day和Hour中包含的其他列合併,以便進一步聚合它們。特別是我需要優先級中每天/每小時的百分比份額(至少有一個非零值總是存在)。

在過去的解決方案中,我遍歷每一行以提取單個值,但這一直很慢。我希望保持它儘可能高效,因爲數據應該在散景服務器應用程序中更新。也許有沒有使用itertuples或類似的解決方案?謝謝!

回答

2
df.groupby(['Day','Hour','Prio']).sum().unstack().fillna(0).astype(int) 
#   Value     
#Prio  Content Critical High Low 
#Day Hour       
#1 6   0  1 0 0 
# 16   0  1 0 0 
# 17   1  0 0 1 
# 19   0  1 0 0 
# 20   0  0 1 0 
#2 10   0  0 1 2 

如果需要,您可以進一步重置索引。

+0

'unstack'是缺少的環節這裏我不知道,沒有它我怎麼能活下去。與我先前謙遜的方法相比,您的解決方案以及'pivot_table'工作得非常好,性能卓越。謝謝! – AdmPicard

2

或者你可以嘗試

pd.pivot_table(df,values='Value',index=['Day','Hour'],columns=['Prio'],aggfunc='sum')\ 
    .fillna(0).astype(int) 


Out[22]: 
Prio  Content Critical High Low 
Day Hour        
1 6   0   1  0 0 
    16   0   1  0 0 
    17   1   0  0 1 
    19   0   1  0 0 
    20   0   0  1 0 
2 10   0   0  1 2 
+0

考慮將結果轉換爲「int」,因爲它們應該表示計數。 – DyZ

+0

我試過這個解決方案,但經過時間測試,它給了每個循環14.6毫秒,而使用@ DYZ的解決方案每循環5.84毫秒 – Vaishali

+0

感謝您使用'pivot_table'函數,它顯示出與'unstack'方法同樣出色的性能,正是我需要的。因爲我想計算相對值,所以我不需要將它們轉換爲整數並將其留下。 – AdmPicard

1

讓我們用​​,unstackreset_indexrename_axis

df.set_index(['Day','Hour','Prio'])['Value']\ 
    .unstack().fillna(0)\ 
    .astype(int).reset_index()\ 
    .rename_axis(None,1) 

輸出:

Day Hour Content Critical High Low 
0 1  6  0   1  0 0 
1 1 16  0   1  0 0 
2 1 17  1   0  0 1 
3 1 19  0   1  0 0 
4 1 20  0   0  1 0 
5 2 10  0   0  1 2