分组行并计算平均值和计数

时间:2017-01-04 21:54:33

标签: python pandas

这是我的数据框:

df = 
UD   QTY   GRADE   TIME_1   TIME_2
1    20    5       22.5     16.1
1    20    5       26.2     19.5
1    20    5       30.0     14.0
1    20    4       20.0     18.5
2    25    4       23.3     19.9

我需要为TIME_1TIME_2的每个组合计算UDQTY的平均值。然后我想添加新列GRADE_COUNT,它将存储每个组的总行数。例如,在上面给出的数据集中,每个组有4行由UD = 1和QTY = 20定义。

结果应该是这个:

df = 

UD  QTY  MEAN_TIME_1   MEAN_TIME_2   COUNT
1   20   24.67         17.02         4
2   25   23.3          19.9          1

我写了这段代码,它对行进行分组,计算平均值并计算值。

groupby_object = df[['UD', 'QTY', 'GRADE', 'TIME_1', 'TIME_2']].groupby(['TIME_1', 'TIME_2])

df = groupby_object.agg('mean').rename(columns = lambda x: x + ' mean').join(pd.DataFrame(groupby_object.size(),columns=['counts'])).reset_index()

但不是计算平均时间,而是计算平均值QTYGRADE,而UD列也会消失。

3 个答案:

答案 0 :(得分:4)

可以在同一步骤中执行所有不同类型的聚合,而无需合并或分配。 groupby.agg允许您使用映射到使用的聚合函数的列字典来执行此操作

df1 = df.groupby(['UD', 'QTY']).agg({'TIME_1': 'mean', 
                                     'TIME_2': 'mean', 
                                     'GRADE':'count'}).reset_index()

   UD  QTY  TIME_1  GRADE  TIME_2
0   1   20  24.675      4  17.025
1   2   25  23.300      1  19.900

答案 1 :(得分:1)

DataFrame.groupby()的参数指定应使用哪些列将行组合成组。所以,如果你写

df.groupby([['TIME_1', 'TIME_2']])

然后Pandas会合并具有相同TIME_1TIME_2值的行。但是,您希望组合具有相同UDQTY值的行。 (如果您还想使用GRADE对行进行分组,只需在适当的位置添加。)所以使用

>>> g = df.groupby([['UD', 'QTY']])

然后你可以在结果对象上调用mean()来获取组的方法。

>>> g.mean()
        GRADE  TIME_1  TIME_2
UD QTY                       
1  20    4.75  24.675  17.025
2  25    4.00  23.300  19.900

同样,您可以调用count()来获取行数。

>>> g.count()
        GRADE  TIME_1  TIME_2
UD QTY                       
1  20       4       4       4
2  25       1       1       1

现在,您可以使用DataFrame将这些部分组合成新的pandas.concat()

>>> m = g.mean()
>>> c = g.count()
>>> new_df = concat([m, c], axis=1)
>>> new_df
        TIME_1  TIME_2  GRADE
UD QTY                       
1  20   24.675  17.025      4
2  25   23.300  19.900      1

剩下的就是将UDQTY从索引列更改为常规列,您可以使用new_df.reset_index()进行更改,并根据自己的喜好更改列名称,您可以通过为new_df.columns指定一个列表来完成。

答案 2 :(得分:1)

试试这个:

In [295]: g = df.groupby(['UD','QTY'], as_index=False)

In [297]: (pd.merge(g[['TIME_1','TIME_2']].mean(),
     ...:           g.size().to_frame('COUNT').reset_index(),
     ...:           on=['UD','QTY'])
     ...: )
     ...:
Out[297]:
   UD  QTY  TIME_1  TIME_2  COUNT
0   1   20  24.675  17.025      4
1   2   25  23.300  19.900      1

或更好一点:

In [301]: g[['TIME_1','TIME_2']].mean().assign(COUNT=g.size().values)
Out[301]:
   UD  QTY  TIME_1  TIME_2  COUNT
0   1   20  24.675  17.025      4
1   2   25  23.300  19.900      1