无法在Python中使用带有两个参数的groupby应用函数

无法在Python中使用带有两个参数的groupby应用函数,python,pandas,function,Python,Pandas,Function,我的问题是关于。我有一个熊猫数据框,如下所示。我想在按时段分组后计算MAPE。然而,我在尝试这样做时遇到了一个错误。我做错了什么 # Create DataFrame df = pd.DataFrame({ 'date': ['2021-01-01', '2021-01-01', '2021-01-02', '2021-01-02', '2021-01-02'], 'period': [1, 2, 1, 2, 3], 'actuals': [50, 43, 42, 51,

我的问题是关于。我有一个熊猫数据框,如下所示。我想在按
时段分组后计算MAPE
。然而,我在尝试这样做时遇到了一个错误。我做错了什么

# Create DataFrame
df = pd.DataFrame({
    'date': ['2021-01-01', '2021-01-01', '2021-01-02', '2021-01-02', '2021-01-02'],
    'period': [1, 2, 1, 2, 3],
    'actuals': [50, 43, 42, 51, 49],
    'forecast': [49, 48, 50, 39, 51]
})

# Define MAPE
def mape(act, fct):
    return np.sum(abs((act - fct)/act))/len(act)

# Try to calculate MAPE for each period (this fails)
df.groupby('period').apply(mape, act='actuals', fct='forecast')
TypeError: mape() got multiple values for argument 'act'

将功能更改为:

def mape(data, act, fct):
    act = data[act]
    fct = data[fct]
    return np.sum(abs((act - fct)/act))/len(act)

使用
groupby.apply
时,组的数据作为第一个参数传递给函数。

将函数更改为:

def mape(data, act, fct):
    act = data[act]
    fct = data[fct]
    return np.sum(abs((act - fct)/act))/len(act)

使用
groupby.apply
时,组的数据作为第一个参数传递给函数。

您可以通过如下更改调用来保持mape()函数的定义不变:

df.groupby('period').apply(lambda x: mape(x['actuals'], x['forecast']))
传递参数的方式需要更改另一个答案所指出的函数定义。这是因为函数除了要访问列名外,还需要访问DataFrame对象才能访问列值

以这种方式调用lambda函数时,该函数已接收参数中的相应值,并且不需要数据帧名称


以这种方式调用函数的优点是,该函数不需要针对pandas环境进行自定义,并且可以与其他通用Python编程逻辑共享。

您可以通过如下更改调用来保持mape()函数的定义不变:

df.groupby('period').apply(lambda x: mape(x['actuals'], x['forecast']))
传递参数的方式需要更改另一个答案所指出的函数定义。这是因为函数除了要访问列名外,还需要访问DataFrame对象才能访问列值

以这种方式调用lambda函数时,该函数已接收参数中的相应值,并且不需要数据帧名称


以这种方式调用函数的优点是,该函数不需要针对pandas环境进行自定义,并且可以与其他通用Python编程逻辑共享。

另一种选择是避免缓慢的
groupby
+
apply
一起使用,以支持作用于整个数据帧和内置的
DataFrame.GroupBy.mean
,在cython中实现

执行计算,然后您需要该系列的平均值(在周期内)


要稍微整理一下,请定义一个函数来计算绝对百分比误差序列,并取其平均值

def ape(act: pd.Series, fct: pd.Series):
    return (act - fct).div(act).abs()

ape(df['actuals'], df['forecast']).groupby(df['period']).mean()

另一种选择是避免缓慢的
groupby
+
apply
,而支持作用于整个数据帧和内置的
DataFrame.groupby.mean
的矢量化操作,后者在cython中实现

执行计算,然后您需要该系列的平均值(在周期内)


要稍微整理一下,请定义一个函数来计算绝对百分比误差序列,并取其平均值

def ape(act: pd.Series, fct: pd.Series):
    return (act - fct).div(act).abs()

ape(df['actuals'], df['forecast']).groupby(df['period']).mean()