熊猫:使用groupby

时间:2017-05-31 09:17:18

标签: python pandas

我有数据框

ID    domain    category    active_seconds
111   vk.com    Social_network   42
111   facebook.com   Social_network   18
222   vk.com      Social_network     50
222   gmail.com   E-mail    50

如果我使用

df.groupby(['category', 'domain']).agg({'ID': pd.Series.nunique, 'active_seconds': np.sum}).rename(columns={'ID': 'all_users', 'active_seconds': 'all_time'}.reset_index()

我得到了它

category domain all_users all_time Social_network vk.com 2 92 Social_network facebook.com 1 18 E-mail gmail.com 1 50

但是有任何方式可以获得这种格式的报告:

category          domain     all_users     all_time
Social_network                   2            110
                   vk.com        2             92
                  facebook.com   1             18

E-mail                           1             50
                   gmail.com     1             50                   

1 个答案:

答案 0 :(得分:1)

您可以按agg DataFramenunique创建新的sum并添加MultiIndex.from_arrays的新等级,最后concat {{3} }}:

#omit reset_index
df1 = df.groupby(['category', 'domain'])
        .agg({'ID': pd.Series.nunique, 'active_seconds': np.sum})
        .rename(columns={'ID': 'all_users', 'active_seconds': 'all_time'})

df2 = df1.groupby('category').agg({'all_users': 'nunique', 'all_time': 'sum'})

df2.index = pd.MultiIndex.from_arrays([df2.index, [''] * len(df2.index)],
                                       names=('category','domain'))
print (df2)
                       all_time  all_users
category       domain                     
E-mail                       50          1
Social_network              110          2

print (pd.concat([df1,df2]).sort_index())
                             all_time  all_users
category       domain                           
E-mail                             50          1
               gmail.com           50          1
Social_network                    110          2
               facebook.com        18          1
               vk.com              92          2

DataFrame的另一个解决方案是按sort_indexassign创建新列:

df2 = df1.groupby('category').agg({'all_users': 'nunique', 'all_time': 'sum'})
         .assign(domain='')
         .set_index('domain', append=True)
print (df2)
                       all_time  all_users
category       domain                     
E-mail                       50          1
Social_network              110          2