Python group by column 和 value_counts 在所有其他列上

时间:2021-03-12 17:04:59

标签: python pandas dataframe group-by

我正在处理这种类型的 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

但我想要的输出是附加所有 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  

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

你可以使用.stack()

.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 :(得分:1)

  1. 将每个 groupby GROUP 对象传递给函数。
  2. .value_counts()CATEGORY 上计算 SHAPE
  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)

enter image description here

相关问题