pandas pivot_table在具有布尔值的列上聚合

时间:2018-05-21 10:38:22

标签: python-3.x pandas dataframe pivot-table pandas-groupby

我有一个df看起来像,

code    y_m       has_id     
1000    201701    True
1000    201701    False
1000    201702    True
1000    201702    True
2000    201701    True
2000    201701    False
2000    201702    False
2000    201702    False
2000    201702    True

我首先通过codey_m分组来计算每个组中True值的百分比,

df.groupby(['code', 'y_m'])['has_id'].apply(lambda x: np.sum(x) / len(x)).reset_index(name='pct_with_id')

然后我也希望得到像

这样的矩阵
      0     1     2             3              
 0   -1     0    201701       201702       
 1   0     0.56   0.5          0.6 
 2   1000  0.75   0.5          1.0   
 3   2000  0.4    0.5          0.33

-1表示一个虚拟值,表示对于特定代码/ y_m单元格不存在值或保持矩阵形状; 0表示所有Truecodey_mcodey_m的百分比,例如:单元格(1,1)True中所有行的df百分比; (1,2)True201701的{​​{1}}与10002000的{​​{1}}的百分比。

是否可以使用df来实现这一目标?

2 个答案:

答案 0 :(得分:2)

您可以使用pivot_table

获得类似内容
dd = pd.pivot_table(
    df, 
    values='has_id', 
    index='code',  
    columns='y_m', 
    margins=True, 
    aggfunc=lambda x: np.sum(x)/len(x)
)
# dd outputs:
y_m   201701    201702       All
code
1000     0.5  1.000000  0.750000
2000     0.5  0.333333  0.400000
All      0.5  0.600000  0.555556

然后可以使用通常的pandas访问方法访问元素。示例:

dd.loc[1000, 'All']
# 0.75
dd.loc[1000, 201702]
# 1.0
dd.loc['All', 'All]
# 0.5555555555555556

答案 1 :(得分:1)

要使pivot_table生效,您需要另一列列出pct_with_id的True百分比。然后,您可以指定values=pct_with_idcolumns=['y_m']index=['code']。您可能需要在0等代码中创建一个新条目,以涵盖所有行的第一个True案例。