基于列计数的自定义分组

2024-05-14 11:04:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据库,里面的产品有一个产品类型和一个产品线(一组产品类型)。我必须计算每种产品类型的平均销售额,到目前为止很简单:

df.groupby('Type')['Sales'].avg()

问题是有些类型的数据很低,例如新产品的数据。因此,在这种情况下,企业希望使用产品线平均值,而不是单一的产品类型平均值

所以本质上,我必须构建一个定制的聚合函数,它将根据组计数改变行为,顺便说一句,当统计数据较低时,它将需要访问整个数据库的信息

解决这个问题的最佳方法是什么

我已经试过分组和循环了。它是有效的,但是我必须把值填回到表中,我不知道怎么做。另一种方法是创建一个自定义聚合函数并通过.agg传递它,但我不知道如何实现它

group = df.groupby('Type')['Sales'].avg()
for name, group in tab_sales_per_machines:
    nmachines = group['Machine'].nunique()
    if nmachines < 5 :
        ... do stuff using df...
    else :
        group['Sales'].avg()

Tags: 数据方法函数数据库类型df产品type
2条回答

您可以尝试使用apply(以获得比agg多一点的灵活性):

def your_func(group):
    nmachines = group.Machine.nunique()
    if nmachines < 5 :
        ... do stuff using df...
        return stuff
    # default is to return Sales avg
    return group.Sales.avg()

df.groupby('Type').apply(your_func)

我设法解决了它通过循环对小组。我在这里发布我的解决方案。这是可行的,但似乎不是最优雅的方式。万一有人有更好的主意,我会很高兴听到的。注意:这个函数比这个复杂一点:我试着把它分解成需要理解的基本部分

def getSalesPerMachine(df) :

    groups  = df[['Type','Sales','Product Line','Machine']].groupby('Type', as_index=False)

    # Build the output table
    tab = groups.agg({'Machine':'nunique', 'Sales':'sum', 'Product Line' : 'max'})
    tab['Annual sales'] = np.nan  ## <  Create the column where I'll put the result.

    for name, group in groups:

        ## If stats is low use the full product line (rescaled)
        nmachines = group.Machine.nunique()

        if nmachines < 5 :

            # Retrieve the product line
            pl = group['Product Line'].max()

            ## Get all machines of that product line
            mypl = df.loc[df['Product Line'] == pl]

            ## Assign to sales the total of the PL rescales for how many machines of the specific type
            sales = mypl.Sales.sum() * nmachines /  mypl.Machine.nunique()

        else :
            # If high stats just return the sum plain and simple
            sales = group.Sales.sum() 

        # Save result (this was where I was stuck before)
        tab['Annual sales'] = \
            np.where(tab['Type']==name, annualSales, tab['Annual sales'])

    return tab

相关问题 更多 >

    热门问题