我有一个数据帧,其中有一个name
列和一个department
列。在name
列中有重复的值有不同的department
值,但所有其他列值是相同的。我想将这些重复平铺为,并将不同的(唯一的)部门值组合到一个列表中。因此,请取每组的第一行,并将department
值更改为该组中唯一department
值的列表。因此生成的数据框应该具有完全相同的列,但在name
列中不存在重复,并且department
列现在具有至少一个元素的列表。如何使用自定义熊猫群组的聚合函数来合并数据帧中的行
我以为使用groupby
和一个自定义聚合函数传递给agg()
但以下完全失败。我的想法是,我的聚合函数会将每个组作为一个数据帧,并且如果对于每个数据帧组我返回了一个系列,那么groupby.agg(flatten_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_group
是不是DF而是一系列其指数是从原来的DF的索引,并将其命名是在原DF和值值一些列该列的名称。
我知道我可以只是做一个for循环在groupby
对象如下
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
点!
任何想法如何实现我的目标agg
或如果for循环是真正的方式。如果for循环是正确的方法,agg
的要点是什么?
谢谢!
感谢您的回答,单行申请完全是老板。我也理解你的'agg'例子,使用字典符号表示,如在“列”中所做的那样。我想我仍然感到困惑的是,如何在参数是函数的地方使用'agg' - 在'agg'中该函数的“规则”是什么?为什么它通过一系列其他随机列?! –
ministry
请参阅'.agg'之前的'.dept'。这意味着我已经将'agg'限制在一个系列中。这意味着'dict(dept = lambda)'指定它将使用'lambda'并调用'dept'列。改变'dict'中的'dept',你将有不同的列名。在这种情况下我不会使用'agg'。我只是想给你一个例子,以便你能更好地了解发生了什么。 – piRSquared
来自'apply'调用的数据框只有'name'和'department'列 - 我怎样才能得到剩下的列呢? – ministry