首页 文章

pandas:在分组后按多列创建单个大小和总和列

提问于
浏览
3

我有一个数据框,我在3列上进行groupby并聚合数值列的总和和大小 . 运行代码后

df = pd.DataFrame.groupby(['year','cntry', 'state']).agg(['size','sum'])

我得到的东西如下:

Image of datafram

现在我想从主列拆分大小子列并仅创建单个大小的列,但希望将总和列保留在主列 Headers 下 . 我尝试了不同的方法,但没有成功 . 这些是我尝试过但无法让事情适合我的方法:

How to count number of rows in a group in pandas group by object?

Converting a Pandas GroupBy object to DataFrame

如果有人能帮我这个,我将不胜感激 .

问候,

2 回答

  • 4

    Setup

    d1 = pd.DataFrame(dict(
            year=np.random.choice((2014, 2015, 2016), 100),
            cntry=['United States' for _ in range(100)],
            State=np.random.choice(states, 100),
            Col1=np.random.randint(0, 20, 100),
            Col2=np.random.randint(0, 20, 100),
            Col3=np.random.randint(0, 20, 100),
        ))
    
    df = d1.groupby(['year', 'cntry', 'State']).agg(['size', 'sum'])
    df
    

    enter image description here


    Answer
    最简单的方法是在 groupby 后才能运行 size

    d1.groupby(['year', 'cntry', 'State']).size()
    
    year  cntry          State        
    2014  United States  California       10
                         Florida           9
                         Massachusetts     8
                         Minnesota         5
    2015  United States  California        9
                         Florida           7
                         Massachusetts     4
                         Minnesota        11
    2016  United States  California        8
                         Florida           8
                         Massachusetts    11
                         Minnesota        10
    dtype: int64
    

    要使用计算的 df

    df.xs('size', axis=1, level=1)
    

    enter image description here

    如果每列的 size 不同,那将非常有用 . 但因为 size 列与 ['Col1', 'Col2', 'Col3'] 相同,我们可以这样做

    df[('Col1', 'size')]
    
    year  cntry          State        
    2014  United States  California       10
                         Florida           9
                         Massachusetts     8
                         Minnesota         5
    2015  United States  California        9
                         Florida           7
                         Massachusetts     4
                         Minnesota        11
    2016  United States  California        8
                         Florida           8
                         Massachusetts    11
                         Minnesota        10
    Name: (Col1, size), dtype: int64
    

    Combined View 1

    pd.concat([df[('Col1', 'size')].rename('size'),
               df.xs('sum', axis=1, level=1)], axis=1)
    

    enter image description here


    Combined View 2

    pd.concat([df[('Col1', 'size')].rename(('', 'size')),
               df.xs('sum', axis=1, level=1, drop_level=False)], axis=1)
    

    enter image description here

  • 2

    piRSquared打败了它,但是如果你必须这样做,并希望保持与列的对齐,并且总和或大小在下面你可以重新索引列以删除大小值,然后添加一个新列以包含大小值 .

    例如:

    group = df.groupby(['year', 'cntry','state']).agg(['sum','size'])
    mi = pd.MultiIndex.from_product([['Col1','Col2','Col3'],['sum']])
    group = group.reindex_axis(mi,axis=1)
    sizes = df.groupby('state').size().values
    group['Tot'] = 0
    group.columns = group.columns.set_levels(['sum','size'], level=1)
    group.Tot.size = sizes
    

    最终看起来像这样:

    Col1 Col2 Col3  Tot
                      sum  sum  sum size
    year cntry State
    2015 US    CA      20    0    4    1
               FL      40    3    5    1
               MASS     8    1    3    1
               MN      12    2    3    1
    

相关问题