我正在尝试生成汇总的数据框(使用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
答案 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