使用Pandas按多个列值对不同行的列表进行分组

时间:2017-02-01 17:09:35

标签: python pandas dataframe group-by sum

我有一个像这样的数据框df1

import pandas as pd
dic = {'A':[0,0,2,2,2,1,5,5],'B':[[1,5,3,8],[1,8,7,5],[7,8,9,5],[3],[1,5,9,3],[0,3,5],[],[4,2,3,1]],'C':['a','b','c','c','d','e','f','f'],'D':['0','8','7','6','4','5','2','2']}
df1 = pd.DataFrame(dic)

看起来像这样:

#Initial dataframe 
   A             B  C  D
0  0  [1, 5, 3, 8]  a  0
1  0  [1, 8, 7, 5]  b  8
2  2  [7, 8, 9, 5]  c  7
3  2           [3]  c  6
4  2  [1, 5, 9, 3]  d  4
5  1     [0, 3, 5]  e  5
6  5            []  f  2
7  5  [4, 2, 3, 1]  f  2

我的目标是对列AC中具有相同值的行进行分组,并合并列B的内容,使结果如下所示:< / p>

#My GOAL
   A                B  C
0  0     [1, 5, 3, 8]  a
1  0     [1, 8, 7, 5]  b
2  2  [3, 7, 8, 9, 5]  c
3  2     [1, 5, 9, 3]  d
4  1        [0, 3, 5]  e
5  5     [4, 2, 3, 1]  f

如您所见,列AC中具有相同项目的行会合并,而如果至少有一个不同,则保留原样。 我的想法是使用groupbysum这样的函数:

df1.groupby(by=['A','C'],as_index=False,sort=True).sum()

但Python返回错误消息:Function does not reduce

你能否告诉我我的代码行有什么问题?为了实现目标,我应该写些什么?

注意:我不关心可以放弃的列D会发生什么。

2 个答案:

答案 0 :(得分:2)

其中一种可能性是在itertools.chain(*iterables)

的帮助下压缩list个列表,直到它耗尽为止
import itertools
df1.groupby(['A', 'C'])['B'].apply(lambda x: list(itertools.chain(*x))).reset_index()

<强> (OR)

sumlambda

一起使用
df1.groupby(by=['A','C'])['B'].apply(lambda x: x.sum()).reset_index()

两者都屈服:

enter image description here

默认情况下,groupby().sum()查找数字类型(标量)值以执行聚合,而不是像list这样的元素集合。

答案 1 :(得分:1)

另一种可能性:

df1.groupby(by=['A','C'],as_index=False,sort=True).agg({'B': lambda x: tuple(sum(x, []))})

结果:

   A  C                B
0  0  a     (1, 5, 3, 8)
1  0  b     (1, 8, 7, 5)
2  1  e        (0, 3, 5)
3  2  c  (7, 8, 9, 5, 3)
4  2  d     (1, 5, 9, 3)
5  5  f     (4, 2, 3, 1)

基于this answer(似乎列表在聚合方面效果不佳)。