熊猫按多列分组,过滤并取平均值的比率

时间:2019-05-01 23:19:47

标签: python pandas lambda filter pandas-groupby

我想用两列对数据帧进行分组,然后过滤小于某个阈值的结果,然后取均值的比率。

示例:

grouped_df = df_test[["bool_column", "A", "B",
        "C", "filter_column"]].groupby(["filter_column", "bool_column"])
grouped_df.describe()

这给了我类似的东西

                   bool_column       A       B       C
filter_column

Name1                 True       <stats> <stats> <stats> [count = 4]
                      False      <stats> <stats> <stats> [count = 2]
Name2                 True       <stats> <stats> <stats> [count = 3]
                      False      <stats> <stats> <stats> [count = 1]

我现在要过滤掉那些计数<2的字段。所以我想要:

                   bool_column       A       B       C
filter_column

Name1                 True       <stats> <stats> <stats> [count = 4]
                      False      <stats> <stats> <stats> [count = 2]
Name2                 True       <stats> <stats> <stats> [count = 3]

在此之后,我要采用列ABC的均值之比。也就是说,对于每个过滤器列,我都需要

colA[True].mean / colb[False].mean

我还是无法使过滤器正常工作。我尝试了以下方法:

  1. grouped_df2 = grouped_df.filter(lambda x: len(x) > 1)
  2. grouped_df2 = grouped_df2.stack()
  3. grouped_df = grouped_df.filter(lambda x: len(x) > 0)

以下方法可以获取比率:

df = grouped_df['A'].mean().unstack('bool_column')
df = df[(df[True] > 0) & (df[False] > 0)]
df['ratio'] = df[True] / df[False]
df = df.drop(columns=[True,False])
df.plot(kind='bar')

1 个答案:

答案 0 :(得分:1)

这是一个可能的解决方案,首先汇总每组的均值和计数:

df = grouped_df.agg([np.mean, 'count'])

然后过滤计数太低的行:

df = df[df['A', 'count'] > 1]

删除不必要的计数列并重命名:

df = df.drop('count', axis=1, level=1)
df.columns = df.columns.get_level_values(0)

要计算平均值,请先对bool_column进行堆栈,然后为每个数据列添加新的ratio列:

df = df.unstack()

for col in df.columns.get_level_values(0).unique():
    df[col, 'ratio'] = df[col, True] / df[col, False]

最后,仅选择ratio列:

df.iloc[:, df.columns.get_level_values(1) == 'ratio']

结果:

                  A      B
  bool_column     ratio  ratio
filter_column       
            1       NaN    NaN
            2  0.857143  0.875