我有df
df = pd.DataFrame(dict(
A=['b', 'a', 'b', 'c', 'a', 'c', 'a', 'c', 'a', 'a'],
B=[[0, 2, 3, 1],
[9, 6, 7, 2],
[6, 0, 1, 4],
[9, 2, 5, 1],
[5, 1, 4, 8],
[8, 5, 6, 6],
[0, 9, 0, 0],
[2, 6, 1, 8],
[7, 3, 2, 6],
[8, 7, 1, 9]]
))
我希望按'A'
进行分组,然后联合'B'
df.groupby('A').B.union()
和df.groupby('A').B.apply(set.union)
都不起作用。
我希望结果是
A
a {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
b {0, 1, 2, 3, 4, 6}
c {1, 2, 5, 6, 8, 9}
Name: B, dtype: object
答案 0 :(得分:5)
问题是你需要在应用联合之前先将它们作为集投射。一种解决方案是使用sum
连接组,然后使用map
转换为设置
In [28]: df.groupby('A').B.sum().map(set)
Out[28]:
A
a {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
b {0, 1, 2, 3, 4, 6}
c {1, 2, 5, 6, 8, 9}
dtype: object
答案 1 :(得分:2)
maxymoo的答案很好,但由于它首先将所有列表添加到一起,因此可能会不必要地占用大量内存(特别是如果有大量重复内容的话)。
相反,您应该首先将列B
转换为集合,之后您可以更有效地减少到单个集合。像这样:
df['B'] = df['B'].map(set)
A B
0 b {0, 1, 2, 3}
1 a {9, 2, 6, 7}
2 b {0, 1, 4, 6}
3 c {9, 2, 5, 1}
4 a {8, 1, 4, 5}
5 c {8, 5, 6}
6 a {0, 9}
7 c {8, 1, 2, 6}
8 a {2, 3, 6, 7}
9 a {8, 1, 9, 7}
df.groupby('A').B.apply(lambda x: reduce(set.union, x))
A
a {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
b {0, 1, 2, 3, 4, 6}
c {1, 2, 5, 6, 8, 9}
Name: B, dtype: object
或者,作为一个单行,如maxymoo所指出的那样:
df.groupby('A').B.apply(lambda x : reduce(set.union, x.map(set)))
答案 2 :(得分:1)
我将使用函数来应用
def f(x):
# grabbing first one so I can
# make a set out of it
first, *rest = x.values.tolist()
# union won't work unless it's on
# a set, it doesn't care about the rest
return set(first).union(*rest)
df.groupby('A').B.apply(f)
A
a {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
b {0, 1, 2, 3, 4, 6}
c {1, 2, 5, 6, 8, 9}
Name: B, dtype: object