2016-03-17 51 views
2

这里想什么,我做给下面的输入:通过catpandas:如何将groupby行的一个子集聚合成单行?

pd.DataFrame({'cat':['A','B','C','B','C','D','C','E'], 'value':[3,6,7,7,9,8,3,1]}) 

cat value 
A   3 
B   6 
C   7 
B   7 
C   9 
D   8 
C   3 
E   1 
  1. 集团和降序排序:

    df.groupby('cat').sum().sort_values('value', ascending=False) 
    
    cat sum 
    C  19 
    B  13 
    D  8 
    A  3 
    E  1 
    
  2. 离开行时,累计加起来不到90 %原样,但其余的行合并成一个新的类别“其他”:

    cat sum 
    C  19 
    B  13 
    Other 12 
    

我怎样做最后一步?

回答

3

result = df.groupby('cat').sum().sort_values('value', ascending=False) 

鸿沟result的总和来获得百分比:

In [139]: result.div(result.sum()) 
Out[139]: 
     value 
cat   
C 0.431818 
B 0.295455 
D 0.181818 
A 0.068182 
E 0.022727 

采取累积和:

In [140]: result.div(result.sum()).cumsum() 
Out[140]: 
     value 
cat   
C 0.431818 
B 0.727273 
D 0.909091 
A 0.977273 
E 1.000000 

,并建立一个布尔面膜这是真正的地方cumsum是< 0.9:

In [141]: result.div(result.sum()).cumsum() < 0.9 
Out[141]: 
    value 
cat  
C  True 
B  True 
D False 
A False 
E False 

选择,总结了非屏蔽行:

row = result.loc[~mask].sum() 
row.name = 'Other' 

使用result.loc[mask]选择真行,并追加了 “其他” 行:

result = result.loc[mask] 
result = result.append(row) 

import pandas as pd 
df = pd.DataFrame({'cat':['A','B','C','B','C','D','C','E'], 'value':[3,6,7,7,9,8,3,1]}) 
result = df.groupby('cat').sum().sort_values('value', ascending=False) 
mask = (result['value'].div(result['value'].sum()).cumsum() < 0.9) 
result = result.loc[mask].append(pd.Series(result.loc[~mask].sum(), name='Other')) 
print(result) 

收益率

 value 
cat   
C   19 
B   13 
Other  12 
+1

不错!我认为可以通过'result.loc [mask] .append(np.Series(result.loc [〜mask] .sum(),name =“Other”)来简化这个过程。' –

+0

是的,这会更简洁: ) – unutbu