Pandas groupby中的行式联盟

时间:2014-07-29 16:41:31

标签: python pandas

我有一个大型数据框,看起来像这样(并且可以使用df=pd.read_clipboard(sep='\s\s+')进行复制粘贴:

    user_nm    month    unique_ips  shifted_ips     halves  quarters    mo_pairs
    100118231   2   set([142.136])  set([])         h1  q1  p1
    100118231   3   set([142.136])  set([142.136])  h1  q1  p2
    100118231   6   set([108.0])    set([142.136])  h1  q2  p3
    100118231   7   set([108.0])    set([108.0])    h2  q3  p4
    100118231   8   set([142.136])  set([108.0])    h2  q3  p4
    100118231   9   set([142.136])  set([142.136])  h2  q3  p5
    100118231   10  set([142.136])  set([142.136])  h2  q4  p5
    100118231   11  set([142.136])  set([142.136])  h2  q4  p6
    100406016   3   set([50.192])   set([])         h1  q1  p2
    100406016   7   set([50.192])   set([50.192])   h2  q3  p4

对于每个用户,我想按halves(或quartersmo_pairs)进行分组,并获得unique_ipsshifted_ips的联合。

我可以像这样分组:

In [265]: a=df.groupby(['user_nm','halves'])

In [266]: a.head()
Out[266]: 

            user_nm month   unique_ips  shifted_ips halves  quarters    mo_pairs
user_nm halves                              
100118231   h1  0   100118231   2   set([142.136])  set([]) h1  q1  p1
        1   100118231   3   set([142.136])  set([142.136])  h1  q1  p2
        2   100118231   6   set([108.0])    set([142.136])  h1  q2  p3
    h2  3   100118231   7   set([108.0])    set([108.0])    h2  q3  p4
        4   100118231   8   set([142.136])  set([108.0])    h2  q3  p4
        5   100118231   9   set([142.136])  set([142.136])  h2  q3  p5
        6   100118231   10  set([142.136])  set([142.136])  h2  q4  p5
        7   100118231   11  set([142.136])  set([142.136])  h2  q4  p6
100406016   h1  8   100406016   3   set([50.192])   set([]) h1  q1  p2
    h2  9   100406016   7   set([50.192])   set([50.192])   h2  q3  p4

但是,当我尝试联合这些行时,出现错误:

In [267]: a.apply(lambda x: x[2] & x[3], axis=1)
TypeError: <lambda>() got an unexpected keyword argument 'axis'

理想情况下,我想要这样的事情:

                  unique_ips    shifted_ips
user_nm   halves        
100118231   h1  set([142.136, 108.0])   set([142.136])
100118231   h2  set([142.136,108.0])    set([142.136,108.0])
100406016   h1  set([50.192])           set([])
100406016   h2  set([50.192])           set([50.192])

我还试过了set_index,但这并未对数据框进行适当分组

b=df.set_index(['user_nm','halves'])

这似乎是一项相对简单的任务,我缺少什么?

1 个答案:

答案 0 :(得分:3)

对此的简短回答是,您需要在减少aggregate对象Pandas GroupBy Aggregate的同时使用groupyby方法。

现在,以下代码段可以解决您的问题

在阅读时正确处理集合:元素以str而不是set

出现
df.unique_ips = df.unique_ips.apply(eval)
df.shifted_ips = df.shifted_ips.apply(eval)

执行groupby

grouped = df.groupby(['user_nm', 'halves'])
my_lambda = lambda x: reduce(set.union, x)
output = grouped.aggregate({'unique_ips': my_lambda,
                            'shifted_ips': my_lambda})

结果是:

                             unique_ips            shifted_ips
user_nm   halves                                              
100118231 h1      set([142.136, 108.0])         set([142.136])
          h2      set([142.136, 108.0])  set([142.136, 108.0])
100406016 h1              set([50.192])                set([])
          h2              set([50.192])          set([50.192])