有条件按声明分组

时间:2019-09-11 22:51:58

标签: python pandas pandas-groupby

我有数据框:

  PRODUCT  SPEED  HEIGHT  LENGTH      DATE
      30       10    5       8         2019-08
      30       13    9       15        2019-08
      31       19    8       12        2019-08
      30       5     6       3         2019-08
      31       11    8       6         2019-09
      30       11    8       6         2019-09
      30       11    8       6         2019-09
      31       11    8       6         2019-09
      31       11    8       6         2019-09

我想生成一个表,其中包含按月划分的SPEED,HEIGHT和LENGTH的平均值。我还想在该表中有一列,当PRODUCT = 30时,该列具有每月总PRODUCT的百分比。

我想要的输出:

  DATE      SPEED   HEIGHT   LENGTH   PRODUCT
  2019-08    11.75    7        9.5      75%
  2019-09     11      8         6       40%

我有以下代码:

avg_summary = df.groupby(['DATE']).agg({'SPEED': 'mean',
                                         'HEIGHT' : 'mean',
                                         'LENGTH': 'mean',
                                         'PRODUCT': 'count'}).reset_index()

这将输出:

  DATE      SPEED   HEIGHT   LENGTH   PRODUCT
  2019-08    11.75    7        9.5      4
  2019-09     11      8         6       5

我知道我可以(df[df.PRODUCT == 30].shape[0])来查找PRODUCT == 30时整个数据框中的计数,但是我无法弄清楚如何按月计算PRODUCT = 30时的实例数。

我认为我可以将PRODUCT = 30时的实例数除以PRODUCT的总数,以获得所需的结果。

任何帮助/提示将不胜感激!谢谢。

3 个答案:

答案 0 :(得分:1)

您非常接近,在进行分组后,过滤PRODUCT == 30上的数据,再次对日期进行分组,然后将大小乘积除以原始的avg_summary

s = df.query('PRODUCT==30').groupby('DATE')['PRODUCT'].size().to_numpy()
avg_summary['PRODUCT'] = s / avg_summary['PRODUCT'] * 100

输出

      DATE  SPEED  HEIGHT  LENGTH  PRODUCT
0  2019-08  11.75       7     9.5     75.0
1  2019-09  11.00       8     6.0     40.0

答案 1 :(得分:0)

您可以将您正在谈论的两件事结合起来,我认为这将为您带来想要的东西。

counts = df[df['PRODUCT']==30].groupby(['DATE']).agg({'PRODUCT': 'count'}).reset_index()

avg_summary['PRODUCT'] = (counts['PRODUCT'] / avg_summary['PRODUCT'])*100

首先,您在PRODUCT = 30上进行过滤,然后按DATE进行分组,从而按月对PRODUCT = 30进行计数。

答案 2 :(得分:0)

您还可以编写一个内联函数以传递给product列。如果要在列中使用%符号,可以使用f字符串:

df = (df.groupby('DATE', as_index=False)
        .agg({'SPEED': 'mean',
              'HEIGHT': 'mean',
              'LENGTH': 'mean',
              'PRODUCT': lambda x: f'{100*(x.eq(30).sum()/len(x)):.0f}%'})
      )


print(df)

      DATE  SPEED  HEIGHT  LENGTH PRODUCT
0  2019-08  11.75       7     9.5     75%
1  2019-09  11.00       8     6.0     40%