gpt4 book ai didi

python - 如何更改 pandas groupby.agg 函数的输入参数?

转载 作者:行者123 更新时间:2023-12-05 09:35:07 27 4
gpt4 key购买 nike

我在将 groupby_object.agg() 方法与我想要更改输入参数的函数一起使用时遇到问题。是否有可用的函数名称资源 .agg() 接受,以及如何将参数传递给它们?

请看下面的例子:

import pandas as pd
import numpy as np

df = pd.DataFrame({'numbers': [1, 2, 3, 2, 1, 3],
'colors': ['red', 'white', 'blue', 'red', 'white', np.nan],
'weight': [10, 10, 20, 5, 10, 20]})

df['colors'].nunique() # Returns 3 as NaN is not counted
df['colors'].nunique(dropna=False) # Returns 4 as NaN is counted

当我然后 groupby 'colors' 时,我如何通过函数传递 dropna=False 参数?

df.groupby('numbers').agg({'colors': 'nunique', 'weight': 'sum'})

最佳答案

虽然 pandas 有很好的语法来聚合字典和 NamedAggs,但这些可能会带来巨大的效率成本。原因是因为没有使用在 cython 中优化和/或实现的内置 groupby 方法,任何 .agg(lambda x: ...).apply(lambda x: ...) 将采用更慢的路径。

这意味着您应该坚持使用可以直接引用或通过别名引用的内置函数。只有作为最后的手段,您才应该尝试使用 lambda:

在这种特殊情况下使用

df.groupby('numbers')[['colors']].agg('nunique', dropna=False)

避免

df.groupby('numbers').agg({'colors': lambda x: x.nunique(dropna=False)})

这个例子表明,虽然输出相同,而且看似微小的变化,但在性能方面会产生巨大的影响,尤其是当组的数量变大时。

import perfplot
import pandas as pd
import numpy as np

def built_in(df):
return df.groupby('numbers')[['colors']].agg('nunique', dropna=False)

def apply(df):
return df.groupby('numbers').agg({'colors': lambda x: x.nunique(dropna=False)})

perfplot.show(
setup=lambda n: pd.DataFrame({'numbers': np.random.randint(0, n//10+1, n),
'colors': np.random.choice([np.NaN] + [*range(100)])}),
kernels=[
lambda df: built_in(df),
lambda df: apply(df)],

labels=['Built-In', 'Apply'],
n_range=[2 ** k for k in range(1, 20)],
equality_check=np.allclose,
xlabel='~N Groups'
)

enter image description here


但是您想进行多次聚合并使用不同的列

groupby 的 .groupby() 部分实际上并没有做那么多;它只是确保映射是正确的。因此,尽管不直观,但与使用 lambda 与更简单的 dict 进行聚合相比,单独使用内置聚合并最终连接结果仍然要快得多。

这是一个同样想要求和权重列的例子,我们可以看到拆分仍然快很多,尽管需要手动加入

def built_in(df):
return pd.concat([df.groupby('numbers')[['colors']].agg('nunique', dropna=False),
df.groupby('numbers')[['weight']].sum()], axis=1)

def apply(df):
return df.groupby('numbers').agg({'colors': lambda x: x.nunique(dropna=False),
'weight': 'sum'})

perfplot.show(
setup=lambda n: pd.DataFrame({'numbers': np.random.randint(0, n//10+1, n),
'colors': np.random.choice([np.NaN] + [*range(100)]),
'weight': np.random.normal(0,1,n)}),
kernels=[
lambda df: built_in(df),
lambda df: apply(df)],

labels=['Built-In', 'Apply'],
n_range=[2 ** k for k in range(1, 20)],
equality_check=np.allclose,
xlabel='~N Groups'
)

enter image description here

关于python - 如何更改 pandas groupby.agg 函数的输入参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66068515/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com