【问题标题】:Including the group name in the apply function pandas python在apply函数pandas python中包含组名
【发布时间】:2015-12-04 07:17:12
【问题描述】:

是否可以指定 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 函数的参数?

【问题讨论】:

    标签: python pandas pandas-groupby apply


    【解决方案1】:

    我认为你应该可以使用nameattribute:

    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: []
    

    【讨论】:

    • 好一个 - transform 怎么样?
    • @Mr_and_Mrs_D 抱歉不明白你的问题,如果你用transform 替换apply 那么它会做同样的事情
    • 谢谢 - 所以x.name 也可以使用转换?我在 groupby 系列上使用转换,我需要 groupby 的密钥在 dict 中使用 - 我正在做一些丑陋的事情,如 df['value'] = df.groupby(['id'])['id'].transform(lambda col: id_to_value_dict[col.unique()[0]])
    • 如果你想要组名,你可以调用 .groups 并从中获取密钥,所以 df.groupby(['id']).groups.keys() 如果没有具体的例子和想要的结果,我很难回答
    • @PlasmaBinturong 在它是 SeriesGroupB 的情况下,它的 name 属性指向转换内的 groupby 键 - 我以这种方式使用它 IIRC
    【解决方案2】:

    对于那些来寻找问题答案的人:

    transform函数pandas python中包含组名

    并最终出现在此线程中,请继续阅读。

    给定以下输入:

    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(即帧)的引用,该子帧包含相应子组的 name 属性。 transform 参数的 name 属性(即 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 文档,因为很可能有一个更简单的矢量化解决方案来解决您可能需要此构造的目的。

    【讨论】:

    • 对相同的属性在转换中不可用感到非常失望。
    猜你喜欢
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多