在应用函数中包括群组名称。

40
有没有办法在groupby()调用中指定使用组名在apply() lambda函数中?
类似于,如果我遍历组,我可以通过以下元组分解获取组键:
for group_name, subdf in temp_dataframe.groupby(level=0, axis=0):
    print group_name

...在apply函数中是否有办法同时获取组名,例如:
temp_dataframe.groupby(level=0,axis=0).apply(lambda group_name, subdf: foo(group_name, subdf)

如何将群组名称作为参数传递给apply lambda函数?
2个回答

61

我认为你应该能够使用name属性:

temp_dataframe.groupby(level=0,axis=0).apply(lambda x: foo(x.name, x))

应该可以工作,示例:
In [132]:
df = pd.DataFrame({'a':list('aabccc'), 'b':np.arange(6)})
df

Out[132]:
   a  b
0  a  0
1  a  1
2  b  2
3  c  3
4  c  4
5  c  5

In [134]:
df.groupby('a').apply(lambda x: print('name:', x.name, '\nsubdf:',x))

name: a 
subdf:    a  b
0  a  0
1  a  1
name: b 
subdf:    a  b
2  b  2
name: c 
subdf:    a  b
3  c  3
4  c  4
5  c  5
Out[134]:
Empty DataFrame
Columns: []
Index: []

2
不错 - transform 怎么样? - Mr_and_Mrs_D
@Mr_and_Mrs_D 对不起,我不理解你的问题。如果你用transform替换apply,那么它会做同样的事情。 - EdChum
1
如果您想获取分组的名称,可以调用.groups并从中获取键,如 df.groupby(['id']).groups.keys()。如果没有具体的示例和所需结果,很难回答您的问题。 - EdChum
仅作为补充:'name'属性不能像列一样使用 - x['name'] 会失败,而 x.name 可以正常工作。您可以通过使用列属性(即 x[<col>] 返回整个 pd.Seriesx.iloc[0][<col>] 获取系列的第一个元素)来获取名称。 - cbcoutinho
1
如果@PlasmaBinturong是一个SeriesGroupB,那么它的“name”属性指向转换内的groupby键 - 我记得我是这样使用的。 - Mr_and_Mrs_D
显示剩余4条评论

7

对于那些寻找答案的人:

在 pandas python 的 transform 函数中包含组名字

并且最终进入了这个帖子,请继续阅读。

给定以下输入:

df = pd.DataFrame(data={'col1': list('aabccc'),
                        'col2': np.arange(6),
                        'col3': np.arange(6)})

数据:

    col1    col2    col3
0   a       0       0
1   a       1       1
2   b       2       2
3   c       3       3
4   c       4       4
5   c       5       5

我们可以通过以下方式访问组名(该组名在调用apply函数的作用域中可见):
df.groupby('col1') \
.apply(lambda frame: frame \
       .transform(lambda col: col + 3 if frame.name == 'a' and col.name == 'col2' else col))

输出:

    col1    col2    col3
0   a       3       0
1   a       4       1
2   b       2       2
3   c       3       3
4   c       4       4
5   c       5       5

请注意,需要调用apply方法才能获得对子pandas.core.frame.DataFrame(即frame)的引用,该子DataFrame保存相应子组的名称属性。transform方法的参数名称属性(即col)是指列/系列名称。
或者,也可以循环遍历每个组,并在每个组内部遍历列:
for grp_name, sub_df in df.groupby('col1'):
    for col in sub_df:
        if grp_name == 'a' and col == 'col2':
            df.loc[df.col1 == grp_name, col] = sub_df[col] + 3

我的用例非常少见,这是实现我的目标的唯一方法(截至pandas v0.24.2)。然而,我建议彻底探索pandas文档,因为你可能需要这种结构的更简单的向量化解决方案。


3
非常失望,transform中没有与这个属性相同的可用选项。 - RSHAP

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