Python 如何使用自定义pandas groupby聚合函数组合数据帧中的行

Python 如何使用自定义pandas groupby聚合函数组合数据帧中的行,python,pandas,group-by,Python,Pandas,Group By,我有一个带有名称列和部门列的数据框。名称列中有重复项,这些重复项具有不同的部门值,但所有其他列的值都相同。我想将这些重复数据展平为一行,并将不同(唯一)的部门值合并到一个列表中。因此,取每组的第一行,只需将部门值更改为该组中唯一的部门值列表。因此,生成的数据帧应该有完全相同的列,但在name列中没有重复,并且department列现在至少有一个元素的列表 我本想使用groupby和一个传递给agg()的自定义聚合函数,但下面的操作完全失败了。我的想法是,我的聚合函数将把每个组作为一个数据帧,如果

我有一个带有
名称
列和
部门
列的数据框。
名称
列中有重复项,这些重复项具有不同的
部门
值,但所有其他列的值都相同。我想将这些重复数据展平为一行,并将不同(唯一)的部门值合并到一个列表中。因此,取每组的第一行,只需将
部门
值更改为该组中唯一的
部门
值列表。因此,生成的数据帧应该有完全相同的列,但在
name
列中没有重复,并且
department
列现在至少有一个元素的列表

我本想使用
groupby
和一个传递给
agg()
的自定义聚合函数,但下面的操作完全失败了。我的想法是,我的聚合函数将把每个组作为一个数据帧,如果我为每个数据帧组返回一个序列,那么
groupby.agg(flatten\u departments)
的输出将是一个数据帧

def flatten_departments(name_group):
    #I thought name_group would be a df of that group 

    #this group is length 1 so this name doesn't actually repeat so just return same row
    if len(name_group) == 1:
        return name_group.squeeze() #turn length-1 df into a series to return, don't worry that department is a string and not a list for now
    else:
        #treat name_group like a df and get the unique departments
        departments = list(name_group['department'].unique())
        name_ser = name_group.iloc[0,:] #take first "row" of this group
        name_ser['department'] = departments #replace department value with list of unique values from group

        return name_ser

my_df = my_df.groupby(['name']).agg(flatten_departments)
这是一场灾难,
name\u group
不是df,而是一个系列,其索引是来自原始df的索引,name是原始df中某个其他列的名称,value是该列的值

我知道我可以在
groupby
对象上执行for循环,如下所示

list_of_ser = []
for name, gp in my_df.groupby(['name']):
    if len(gp) == 1:
        list_of_ser.append(gp.squeeze())
    else:
        new_ser = gp.iloc[0,:]
        new_ser['department'] = list(gp['department'].unique())
        list_of_ser.append(new_ser)

new_df = pd.DataFrame(list_of_ser, columns=my_df.columns)
但我只是认为这就是《代码》的重点

任何关于如何使用
agg
或者for循环是否真的是正确的方法来实现我的目标的想法。如果for循环是正确的方式,那么
agg
的意义是什么

谢谢大家!

df = pd.DataFrame(
    dict(
        name=list('ABCDEFGACEF'),
        dept=list('xyxyzxyzyxz')
    )
)

df.groupby('name').dept.apply(list).reset_index()


agg
可以这样使用

df.groupby('name').dept.agg(dict(dept=lambda x: list(x))).reset_index()

如果需要保留所有其他列

df = pd.DataFrame(
    dict(
        name=list('ABCDEFGACEF'),
        dept=list('xyxyzxyzyxz')
    )
)

g = df.groupby('name')
pd.concat([g.dept.apply(list), g.first().drop('dept', 1)], axis=1).reset_index()

谢谢你的回答,那一行申请完全是老大。我也理解您的
agg
示例使用字典表示法,如“do for column”。我想我仍然困惑的是在参数是函数的情况下如何使用
agg
——在
agg
中该函数的“规则”是什么?为什么它被传递给其他随机列的序列?!请参阅
.agg
之前的
.dept
。这意味着我已经将
agg
限制为一个系列。这意味着
dict(dept=lambda)
指定它将使用
lambda
并调用列
dept
。更改
目录中的
部门
,您将拥有不同的列名。在这种情况下,我不会使用
agg
。我只是想给你举个例子,让你更好地了解发生了什么。从
apply
调用中产生的数据帧只有
name
department
列-我如何将其余列也取回?