带条件熊猫分组

时间:2018-08-21 08:35:52

标签: python pandas pandas-groupby

我正在尝试生成汇总的数据框(使用groupby)。虽然我之前已经做过基本的聚合,但这一聚合条件更为复杂。我已经尝试过网络帮助,但无法正常工作。

样本数据:

df = pd.DataFrame({'indi_id': [1,1,1,2,2],
                   'co_id': [1,1,2,2,3],
                   'relationship': ['shareholder', 'signatory', 'shareholder', 'shareholder', 'director'],
                   'co_type': ['SP', 'SP', 'PT', 'PT', 'SP'],
                   'co_nw': [10,10,100,100,2],
                   'sh_perc': [100, np.nan, 3, 4, np.nan]})

我需要做的是在下面生成一个摘要数据框(groupby:indi_id):

indi_id: 'groupby field' 
num_cos_assoc: 'nunique'(co_ID) - no problems here
num_companies_assoc_sh: nunique(co_ID) where relationship = 'shareholder'
num_SP_companies_assoc: nunique(co_ID) where co_type = 'SP'
total_nw_co_sh: sum(co_nw*sh_prec) where relationship = 'shareholder' 

以下示例结果:

Indi_ID num_cos_assoc   num_companies_assoc_sh  num_SP_companies_assoc  total_nw_co_sh
1       2               2                       1                       1300
2       2               1                       0                       400

2 个答案:

答案 0 :(得分:1)

将自定义函数与GroupBy.apply一起使用,因为agg的设计是分别与每个列一起使用,因此由其他列进行过滤确实存在问题:

def f(x):
    a = x['co_id'].nunique()
    b = x.loc[x['relationship'] == 'shareholder', 'co_id'].nunique()
    c = x.loc[x['co_type'] == 'SP', 'co_id'].nunique()
    d = x.loc[x['relationship'] == 'shareholder', ['co_nw', 'sh_perc']]
    d = d['co_nw'].mul(d['sh_perc'], fill_value=1).sum()
    cols =['num_cos_assoc','num_companies_assoc_sh','num_SP_companies_assoc','total_nw_co_sh']
    return pd.Series([a,b,c,d], index=cols)

df1 = df.groupby('indi_id').apply(f).reset_index()
print (df1)
   indi_id  num_cos_assoc  num_companies_assoc_sh  num_SP_companies_assoc  \
0        1            2.0                     2.0                     1.0   
1        2            2.0                     1.0                     1.0   

   total_nw_co_sh  
0          1300.0  
1           400.0  

答案 1 :(得分:0)

这是不使用自定义功能的一种方法,尽管它实际上与jezrael的解决方案可以做的一样:

df.groupby('indi_id').apply(lambda x: pd.Series([
                   x.co_id.nunique(),
                   x.loc[x.relationship == 'shareholder'].co_id.nunique(),
                   x.loc[x.co_type == 'SP'].co_id.nunique(),
                   x.loc[x.relationship == 'shareholder'][['co_nw','sh_perc']].prod(axis = 1).sum()],
    index = ['num_cos_assoc','num_companies_assoc_sh','nump_SP_companies_assoc','total_nw_co_sh']))

和相应的输出:

           num_cos_assoc num_companies_assoc_sh nump_SP_companies_assoc total_nw_co_sh
indi_id
1          2.0           2.0                     1.0                    1300.0 
2          2.0           1.0                     1.0                    400.0