pandas groupby和join list

fas*_*oth 25 python pandas

我有一个数据帧df,有两列,我想组合一列并加入列表属于同一组,例如:

column_a, column_b
1,         [1,2,3]
1,         [2,5]
2,         [5,6]
Run Code Online (Sandbox Code Playgroud)

过程结束后:

column_a, column_b
1,         [1,2,3,2,5]
2,         [5,6]
Run Code Online (Sandbox Code Playgroud)

我想保留所有重复项.我有以下问题:

  • 数据帧的dtypes是对象.convert_objects()不会自动将column_b转换为列表.我怎样才能做到这一点?
  • df.groupby(...).apply(lambda x:...)中的函数适用于什么?x的形式是什么?清单?
  • 解决我的主要问题?

提前致谢.

Tom*_*ger 37

objectdtype是一个全能型dtype,基本上不是指int,float,bool,datetime或timedelta.所以它将它们存储为列表.convert_objects尝试将列转换为其中一个dtypes.

你要

In [63]: df
Out[63]: 
   a          b    c
0  1  [1, 2, 3]  foo
1  1     [2, 5]  bar
2  2     [5, 6]  baz


In [64]: df.groupby('a').agg({'b': 'sum', 'c': lambda x: ' '.join(x)})
Out[64]: 
         c                b
a                          
1  foo bar  [1, 2, 3, 2, 5]
2      baz           [5, 6]
Run Code Online (Sandbox Code Playgroud)

这会按列中的值对数据框进行分组a.阅读更多关于[groupby]的信息.(http://pandas.pydata.org/pandas-docs/stable/groupby.html).

这是一个常规列表sum(连接)就像[1, 2, 3] + [2, 5]

  • 为什么不只是 `'c': ' '.join` (4认同)

qww*_*wwq 10

df.groupby('column_a').agg(sum)
Run Code Online (Sandbox Code Playgroud)

这是因为运算符重载sum将列表连接在一起.得到的df的索引将是以下值column_a:

  • 很好的解决方案(7年后实现)。推论观察:当“sum”同时列出列表和数字时,单个“.agg(sum)”仅对数字列进行求和。在这种情况下,字典 `{'a': sum, 'b': sum}` -- 感谢 @TomAugspurger -- 工作完美! (2认同)

moz*_*way 7

接受的答案建议使用groupby.sum,这对于少量列表工作得很好,但是使用 sum 来连接列表是二次的

对于大量列表,更快的选择是使用itertools.chain或 列表理解:

df = pd.DataFrame({'column_a': ['1', '1', '2'],
                   'column_b': [['1', '2', '3'], ['2', '5'], ['5', '6']]})
Run Code Online (Sandbox Code Playgroud)

itertools.chain

from itertools import chain
out = (df.groupby('column_a', as_index=False)['column_b']
         .agg(lambda x: list(chain.from_iterable(x)))
       )
Run Code Online (Sandbox Code Playgroud)

列表理解:

out = (df.groupby('column_a', as_index=False, sort=False)['column_b']
         .agg(lambda x: [e for l in x for e in l])
      )
Run Code Online (Sandbox Code Playgroud)

输出:

  column_a         column_b
0        1  [1, 2, 3, 2, 5]
1        2           [5, 6]
Run Code Online (Sandbox Code Playgroud)

速度对比

使用示例的 n 次重复来显示要合并的列表数量的影响:

test_df = pd.concat([df]*n, ignore_index=True)
Run Code Online (Sandbox Code Playgroud)

比较 pandas 列表合并 groupby

注意。还比较了方法 ( agg(lambda x: np.concatenate(x.to_numpy()).tolist()))。