Python如何从单个列计算多个平均值,然后根据另一列中的值选择要平均的行

时间:2018-12-28 03:22:37

标签: python pandas

[编辑:底部的重写问题]

我试图弄清楚如何计算“部分列”平均值和计数,而不是使用所有值。在伪SQL中,我想要SELECT的所有值WHERE id = 10,然后= 20,依此类推。我假设有一种pythonic(pandastic?)方式可以做到这一点,而无需使用for循环。

示例:df具有3列和数千行:caseidvalue。大小写是唯一的,id可以重复,值是数字。

case    id  value
1       10  100
2       10  500
3       20  200
4       20  150
5       20  125

我想对每个id的值进行计数并计算其平均值,然后将它们放在新的列中。 。

case    id  value   n_vals  av_val
1       10  100     2       300
2       10  500
3       20  300     3       200
4       20  150
5       20  150

。 。 。然后删除casevalue并为每个ID仅保留一行(它们现在是唯一的):

id  n_vals  av_val
10  2       300
20  3       200

我知道如何为整个列找到lenmean,但是不确定如何为部分列找到它。


[重写问题]:

我有7个变量的20000265 obs df。 case是唯一的,Id可以重复。:

case        Id      title           n_words n_chars rating  rating2
20000260    131258  The Pirates     2       11      2.5     2.5
20000261    131258  The Pirates     2       11      3.5     3.5
20000262    131258  The Pirates     2       11      4.5     4.5
20000263    131260  Rentun Ruusu    2       12      3       3
20000264    131260  Rentun Ruusu    2       12      5       5
20000265    131262  Innocence       1       9       4       4

我想计算每个Id的评级数量和平均评级。这些值将以n_ratingsav_rating的形式添加到df中,从而替换ratingrating2,并为每个Id汇总在一行上。我想保留所有其他列,生成如下内容:

case        Id      title           n_words n_chars n_ratings   av_rating
20000260    131258  The Pirates     2       11      3           3.5
20000263    131260  Rentun Ruusu    2       12      2           4
20000265    131262  Innocence       1       9       1           4

基于下面@ U9_Forward的回答,我已经尝试过:

df = 
    (df.
        groupby('Id', as_index = False).
        agg({'rating':'count', 'rating2':'mean'}).
        # rename(columns = {'rating':'n_ratings', 'rating2':'av_rating'}))
        rename(columns = {'Id':'Id', 'title':'title',
                      'num_words':'num_words', 'num_chars':'num_chars',
                      'rating':'n_ratings', 'rating2':'av_rating'}, axis=1))

但是,这仅保留了Id管道中使用的3列(n_ratingsav_ratinggroupby().agg()),例如:

0   1   49695       3.921240
1   2   22243       3.211977
2   3   12735       3.151040

我尝试将所有列名都包含在rename()字典中,但是得到了相同的结果。

两个问题:

  1. 是否有agg()的参数或实现此目标的另一种方法 理想的结果?
  2. 我在Jupyter获得了FutureWarning,并已阅读 不建议使用带有rename()的字典,否则很快就会使用。什么是 重命名cols的新首选方法?

2 个答案:

答案 0 :(得分:3)

groupbyaggrename一起使用:

print(df.groupby('id',as_index=False).agg({'case':'count','value':'mean'}).rename({'case':'n_vals','value':'av_val'},axis=1))

输出为:

   id  n_vals  av_val
0  10       2     300
1  20       3     200

编辑:

df[['n_ratings','av_rating']]=df[['Id','title']].join(df.groupby(['Id','title']).agg({'rating':'count','rating2':'mean'}), on=['Id','title'])[['rating','rating2']]
print(df.drop_duplicates(keep='last',subset='Id'))

答案 1 :(得分:0)

import pandas as pd
df = pd.DataFrame.from_dict({'case': [1,2,3,4,6],
                             'id': [10,10,20,20,20],
                             'value':[100,500,300,150,150],
                             })

df['n_vals'] = df.groupby(['id'])['id'].transform('count')
df['av_val'] = df.groupby(['id'])['value'].transform('mean')

print (df)
#   case  id  value  n_vals  av_val
#0     1  10    100       2   300.0
#1     2  10    500       2   300.0
#2     3  20    300       3   200.0
#3     4  20    150       3   200.0
#4     6  20    150       3   200.0

通过这种方式,您可以保留每一行并查看它们的n_valsav_val,而不是使用常规的groupby agg函数丢失数据