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
列-我如何将其余列也取回?