Python Pandas自定义聚合函数

13
Dataframe:
  one two
a  1  x
b  1  y
c  2  y
d  2  z
e  3  z

grp = DataFrame.groupby('one')
grp.agg(lambda x: ???) #or equivalent function

grp.agg的期望输出:

one two
1   x|y
2   y|z
3   z

在整合数据框之前,我的聚合函数是"|".join(sorted(set(x)))。理想情况下,我希望组中有任意数量的列,并且agg返回每个列项目的"|".join(sorted(set()),就像上面的两个一样。我还尝试了np.char.join()

热爱Pandas,它让我从一个800行的复杂程序变成了400行轻松愉快的散步。谢谢你:)

3个回答

16

你离成功很近了:

In [1]: df.groupby('one').agg(lambda x: "|".join(x.tolist()))
Out[1]:
     two
one
1    x|y
2    y|z
3      z

扩展答案以处理排序并仅获取集合:

In [1]: df = DataFrame({'one':[1,1,2,2,3], 'two':list('xyyzz'), 'three':list('eecba')}, index=list('abcde'), columns=['one','two','three'])

In [2]: df
Out[2]:
   one two three
a    1   x     e
b    1   y     e
c    2   y     c
d    2   z     b
e    3   z     a

In [3]: df.groupby('one').agg(lambda x: "|".join(x.order().unique().tolist()))
Out[3]:
     two three
one
1    x|y     e
2    y|z   b|c
3      z     a

太棒了。我正在hack可怕的grp2.agg(lambda x: u"|".join(sorted(set(map(str, x.tolist())))))。感谢您向我展示如何真正使用数组!哪里有好的参考资料?再次感谢。 - brian_the_bungler
说实话,使用Ipython并尝试编写代码片段对我的理解比任何其他资源都更有帮助。但Wes McKinney的《Python数据分析》是一个很好的参考资料。 - Zelazny7
你能否分享一些你的mongoDB代码以及如何将其与pandas配合使用?我正试图找出一个一致的工作流程来处理非常大的数据集(但不是'big data')。如果你愿意,我可以提一个适当的SE问题。我还想到了另一个资源:Wes在2012年pycon教程。它非常详细,帮助我巩固了几个概念。 - Zelazny7
我很乐意发布它,但我认为采用问题格式会更好。看到别人的回答也很有趣。这个周末我会有时间好好处理它。 - brian_the_bungler
谢谢,我在这里创建了一个问题:https://dev59.com/cmYq5IYBdhLWcg3wtCzO - Zelazny7
显示剩余2条评论

2

只是对被接受的答案进行阐述:

最初的回答

df.groupby('one').agg(lambda x: "|".join(x.tolist()))

请注意,df.groupby('one')的类型是SeriesGroupBy。并且在该类型上定义了agg函数。如果您查看此函数的文档,它说它的输入是一个作用于Series的函数。这意味着上述lambda中的x类型为Series。
另一个要注意的是,将agg函数定义为lambda并不是必需的。如果聚合函数比较复杂,可以像下面一样单独定义为常规函数。唯一的约束是x类型应为Series(或与之兼容)。
def myfun1(x):
    return "|".join(x.tolist())

然后:

df.groupby('one').agg(myfun1)

1

有一种更好的字符串连接方式,在pandas 文档 中有详细介绍。
所以我更喜欢这种方式:

In [1]: df.groupby('one').agg(lambda x: x.str.cat(sep='|'))
Out[1]:
     two
one
1    x|y
2    y|z
3      z

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接