【问题标题】:Groupby and Value Counting categoriesGroupby 和值计数类别
【发布时间】:2021-12-09 05:38:53
【问题描述】:

我有一个数据框,其中每一行代表产品销售。这些链接到订单号(可以有多个产品),每个订单都有价格和颜色。我需要按订单编号对它们进行分组,并获得一列计算该订单行的每种产品类型。

df = pd.DataFrame({'Product': ['X','X','Y','X','Y','W','W','Z','W','X'],
                   'Order #': ['01','01','02','03','03','03','04','05','05','05'],
                   'Price': [100,100,650,50,700,3000,2500,10,2500,150],
                   'Color': ['RED','BLUE','RED','RED','BLUE','GREEN','RED','BLUE','BLUE','GREEN']})

使用 count 的“常规”分组表达式不是我想要的。

# Aggregate 
ag_func = {'Product Quant.': pd.NamedAgg(column='Product', aggfunc='count'),
           'Total Price': pd.NamedAgg(column='Price', aggfunc='sum'),
           'Color Quant.': pd.NamedAgg(column='Color', aggfunc='count')}

# Test
test = df.groupby(pd.Grouper(key='Order #')).agg(**ag_func).reset_index()

我可以通过对每个类别(产品/颜色)使用 get_dummies 然后使用 sum 聚合函数来解决这个问题。这对于较小的数据集来说很好,但在我的现实世界中,有几十个类别,而且新的集合包含不同的类别......

这是我想出的“解决方案”

# Dummy 
df_dummy = pd.get_dummies(df, prefix='Type', prefix_sep=': ', columns=['Product', 'Color'])

ag_func2 = {'Product Quant.': pd.NamedAgg(column='Order #', aggfunc='count'),
            'W total': pd.NamedAgg(column='Type: W', aggfunc='sum'),
            'X total': pd.NamedAgg(column='Type: X', aggfunc='sum'),
            'Y total': pd.NamedAgg(column='Type: Y', aggfunc='sum'),
            'Z total': pd.NamedAgg(column='Type: Z', aggfunc='sum'),
            'Total Price': pd.NamedAgg(column='Price', aggfunc='sum'),
            'Color BLUE': pd.NamedAgg(column='Type: BLUE', aggfunc='sum'),
            'Color GREEN': pd.NamedAgg(column='Type: GREEN', aggfunc='sum'),
            'Color RED': pd.NamedAgg(column='Type: RED', aggfunc='sum')}

solution = df_dummy.groupby(pd.Grouper(key='Order #')).agg(**ag_func2).reset_index()

注意第 1 行的 2 X 产品和第 5 行的 2 BLUES。这种行为是我需要的,但这对于在多个数据集上重复使用来说太复杂了。我尝试使用 pivot_tables 但没有成功。

我是否应该只定义一个函数来遍历分类列,对这些列进行虚拟化,然后使用虚拟变量的总和聚合对一组列进行分组?

谢谢

【问题讨论】:

    标签: python pandas pandas-groupby categories


    【解决方案1】:

    IIUC 你的问题是为所有创建的假人输入所有pd.NamedAgg,也许你可以单独进行操作。先创建组对象,然后concat对不同的列进行不同的操作。

    gr = df.groupby('Order #')
    res = pd.concat([
        # equivalent to count the orders
        gr.size().to_frame(name='Product Quant.'),
        # equivalent to dummy then sum the dummy product columns
        gr['Product'].value_counts().unstack(fill_value=0).add_suffix(' Total'),
        # sum the price to get the total
        gr['Price'].sum().to_frame(name='Total Price'),
        # equivalent to sum the dummy color columns
        gr['Color'].value_counts().unstack(fill_value=0).add_prefix('Color ')
    ], axis=1)
    
    print(res)
             Product Quant.  W Total  X Total  Y Total  Z Total  Total Price  \
    Order #                                                                    
    01                    2        0        2        0        0          200   
    02                    1        0        0        1        0          650   
    03                    3        1        1        1        0         3750   
    04                    1        1        0        0        0         2500   
    05                    3        1        1        0        1         2660   
    
             Color BLUE  Color GREEN  Color RED  
    Order #                                      
    01                1            0          1  
    02                0            0          1  
    03                1            1          1  
    04                0            0          1  
    05                2            1          0  
    

    所以基本上在这种情况下,groupby.value_counts.unstack 等价于get_dummies.groupby.sum

    为了进一步使用,而不是

    df.groupby('Order #')['Product'].value_counts().unstack(fill_value=0)
    

    您可以通过pivot_table 获得相同的结果:

    df.pivot_table(index='Order #', columns='Product', aggfunc='size', fill_value=0)
    

    【讨论】:

    • 好答案@Ben ;)
    • 太棒了!我必须这样做很多次,我正在考虑用你的方法定义一个函数。
    • @jcf 祝你好运:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 2018-12-08
    • 2016-09-17
    • 2022-10-25
    • 1970-01-01
    • 2017-04-23
    • 2011-11-09
    相关资源
    最近更新 更多