Pandas在多列上进行“groupby”和“apply”函数操作。

6

如果我有一个函数f,我要将其应用于一组列多次,那么有没有更Pythonic的方法呢?目前,我的做法是这样的。

newdf=df.groupby(['a', 'b']).apply(lambda x: f(x, 1))
newdf.columns=['1']
newdf['2']=df.groupby(['a', 'b']).apply(lambda x: f(x, 2))
newdf['3']=df.groupby(['a', 'b']).apply(lambda x: f(x, 3))
newdf['4']=df.groupby(['a', 'b']).apply(lambda x: f(x, 4))

有没有更好的方法去做呢?

谢谢。


1
请提供一个数据框示例和期望的输出。 - J...S
我也删除了我的回答,因为我认为它不够符合Python的风格,并且pandas的groupby操作可能会有些棘手。我将在这里留下一些提示,你可以尝试使用以下代码:newdf = pd.concat(df.groupby(['a', 'b']).apply(lambda x: f(x, i)) for i in range(1, 5), axis=1)。同时提供一个数据框示例会更有帮助。 - Jay Calamari
1
@Linda,你能告诉我们这个函数在做什么吗? - Fourier
我同意其他人的看法,如果你能分享一个 mcve,那么帮助你就会变得容易。根据函数的不同,你甚至可以摆脱 apply - rpanai
4个回答

2

这个对于我来说已经足够Pythonic了:

columns_dict = dict()
for i in range(1, 5):
    columns_dict[str(i)] = df.groupby(["a", "b"]).apply(lambda x: f(x, i))

pd.DataFrame(columns_dict)

1

你可以这样做:

pandas.DataFrame([df.groupby(['a','b']).apply(lambda x : f(x,i)) for i in range(1,5)])

如果您想要与初始数据框具有相同的列名,则请转置新的数据框。

这与Jay Calamari的答案没有显著的不同。 - rpanai
1
Jay Calamari的解决方案甚至都不起作用,因为pandas.concat函数需要将参数作为列表传递。他那里缺少一些括号! - Neroksi

0
使用 agg() 函数来从单个 groupby() 中计算多个值:
df.groupby(['a', 'b']).agg([
    ('1': lambda x: f(x, 1)),
    ('2': lambda x: f(x, 2)),
    ('3': lambda x: f(x, 3)),
    ('4': lambda x: f(x, 4)),
])

或者等价地:

df.groupby(['a', 'b']).agg([(str(i), lambda x: f(x, i)) for i in range(1, 5)])

对于 df = pd.DataFrame({'a': [5], 'b':[3]})def f(x,i): return x**i 这两个代码,它们是否能够正常工作? - user8864088
@astro123:我不知道,它会吗?我看起来像Python解释器吗? - John Zwinck
显然不是。:) 我正在练习那个pandas示例,但它没有起作用,我在想为什么它不起作用? - user8864088
很遗憾,.agg不支持通过x.name索引。 - Tom

0

Pandas groupby.apply 可以接受任意参数和关键字参数,并将它们传递给分组函数。此外,您还可以创建一个将列映射到参数的字典。最后,您还可以重复使用一个 groupby 对象,该对象可以在循环之外定义。

argmap = {'2': 2, '3': 3, '4': 4}

grouper = df.groupby(['a', 'b'])

for k, v in argmap.items():
    newdf[k] = grouper.apply(f, v)

我认为他想要将多个参数传递给apply函数,而不是多次调用apply函数。当需要在单个调用中使用这两列时,这一点非常重要。 - Tom

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