繁体   English   中英

Python 按列分组,在所有其他列上按 value_counts

[英]Python group by column and value_counts on all other columns

我正在处理这种类型的df:

import pandas as pd

df = pd.DataFrame({'GROUP': ['A', 'A', 'B', 'B', 'C', 'C','A', 'A', 'B', 'B', 'C', 'C','B', 'B', 'C', 'C','A'], 'CATEGORY': ['ORANGE', 'WHITE', 'WHITE','ORANGE','ORANGE','BLACK', 'WHITE', 'BLACK', 'BROWN','BLACK','ORANGE','BLACK', 'WHITE', 'WHITE', 'WHITE', 'BLACK', 'BLACK'], 
                   'SHAPE':['SQUARE','TRIANGLE','SQUARE','CIRCLE','CIRCLE','CIRCLE','SQUARE','CIRCLE','TRIANGLE','CIRCLE','CIRCLE','SQUARE','CIRCLE','TRIANGLE','CIRCLE','SQUARE','CIRCLE']})

df.head()

  GROUP CATEGORY SHAPE
0   A   ORANGE  SQUARE
1   A   WHITE   TRIANGLE
2   B   WHITE   SQUARE
3   B   ORANGE  CIRCLE
4   C   ORANGE  CIRCLE

我正在尝试按GROUP分组并对 df 中的所有列进行值计数,保持前 n 次出现。 所以这里有一个关于单列的例子:

df.groupby('GROUP')['CATEGORY'].apply(lambda x: x.value_counts(normalize=True).head(2)).to_frame()

               CATEGORY
GROUP       
A      WHITE    0.400000
       BLACK    0.400000
B      WHITE    0.500000
       BROWN    0.166667
C      BLACK    0.500000
       ORANGE   0.333333

但我想要的 output 将是 append 所有的 value_counts,像这样:

                CATEGORY          SHAPE
GROUP       
A      WHITE    0.400000  CIRCLE   0.400000
       BLACK    0.400000  SQUARE   0.400000 
B      WHITE    0.500000  CIRCLE   0.500000
       BROWN    0.166667  TRIANGLE 0.333333
C      BLACK    0.500000  CIRCLE   0.666667
       ORANGE   0.333333  SQUARE   0.333333  

理想情况下,将列重命名为:

       CATEGORY PERC      SHAPE    PERC
GROUP       
A      WHITE    0.400000  CIRCLE   0.400000
       BLACK    0.400000  SQUARE   0.400000 
B      WHITE    0.500000  CIRCLE   0.500000
       BROWN    0.166667  TRIANGLE 0.333333
C      BLACK    0.500000  CIRCLE   0.666667
       ORANGE   0.333333  SQUARE   0.333333  

任何想法?

你可以使用.stack()

和列表 comp 中的.concat()来处理每个唯一的列类型。 SHAPECATEGORY

但是,此解决方案最多可以处理 n 个唯一类型。

s = df.set_index('GROUP').stack()\
      .groupby(level=[0,1])\
      .value_counts(normalize=True).groupby(level=[0,1]).head(2) #< change 2 for your val.

dfs = pd.concat([s[s.index.isin([i],1)].reset_index()\
                                       .rename(columns={'level_2' : i, 0  : 'PERC'})\
                                       .drop('level_1',1).set_index('GROUP')
                 for i in s.index.get_level_values(1).unique()],axis=1)


print(dfs)

     CATEGORY      PERC     SHAPE      PERC
GROUP                                       
A        BLACK  0.400000    CIRCLE  0.400000
A        WHITE  0.400000    SQUARE  0.400000
B        WHITE  0.500000    CIRCLE  0.500000
B        BLACK  0.166667  TRIANGLE  0.333333
C        BLACK  0.500000    CIRCLE  0.666667
C       ORANGE  0.333333    SQUARE  0.333333
  1. 将每个 groupby GROUP object 传递到 function 中。
  2. CATEGORYSHAPE上计算.value_counts()
  3. CATEGORYSHAPE连接在一起。 axis=1对于使数据排在同一行很重要。
def group_my_data(x):
    category = x['CATEGORY'].value_counts(normalize=True).rename_axis('CATEGORY').reset_index(name='PERC')
    shape = x['SHAPE'].value_counts(normalize=True).rename_axis('SHAPE').reset_index(name='PERC')
    return pd.concat([category, shape], axis=1).head(2)

df = df.groupby('GROUP', as_index=True).apply(group_my_data).reset_index(level=-1, drop=True)

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM