pandas groupby 中的按行联合

Mik*_*ike 5 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
Run Code Online (Sandbox Code Playgroud)

对于每个用户,我想按halves(or quarters, or mo_pairs)分组并获得unique_ipsand 的并集shifted_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
Run Code Online (Sandbox Code Playgroud)

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

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

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

                  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])
Run Code Online (Sandbox Code Playgroud)

我也试过set_index,但这并没有适当地对数据框进行分组

b=df.set_index(['user_nm','halves'])
Run Code Online (Sandbox Code Playgroud)

这似乎是一个相对简单的任务,我错过了什么?

goo*_*ofd 5

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

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

阅读时正确处理 set:元素出现str和不出现set

df.unique_ips = df.unique_ips.apply(eval)
df.shifted_ips = df.shifted_ips.apply(eval)
Run Code Online (Sandbox Code Playgroud)

做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})
Run Code Online (Sandbox Code Playgroud)

结果是:

                             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])
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案,对于Python 3,你需要导入reduce:`from functools import reduce` (2认同)
  • 我建议不要处理 `functools.reduce`,而是使用 `my_lambda = lambda x: set.union(*x)`。根据文档,该功能自 Python 2.6 起可用。 (2认同)