Pandas mean()函数计算结果自动取整为0.25倍数问题排查
问题:Pandas计算加权平均值错误,结果被取整为0.25倍数?
我用Pandas计算DataFrame中Rating列按Period分组的加权平均值时遇到问题,mean()返回结果总是0.25的倍数。比如2023-1周期手动计算应为(4*4.0+10*2.0+3*1.0+23*3.0)/(4+10+3+23)=2.7,但Pandas返回2.5。
DataFramegroups包含Period、问题列、Count和Rating列,我的代码如下:
def create_bar_chart(df: pd.DataFrame, question: str): groups = df.groupby(['Period', question]).size().reset_index(name='Count') groups['Rating'] = groups.apply(lambda row: to_rating(question, row[question]), axis=1) groups['Rating'] = groups['Rating'].astype(float) print(groups.dtypes) print(groups.tail(5)) for period in groups['Period'].unique(): period_ratings = groups.loc[groups['Period'] == period, 'Rating'] mean_rating = period_ratings.mean() print(f'{period}: {mean_rating:.4f}') # matplotlib code...
输出显示各列类型正确,但所有均值结果均为0.25的倍数:
2018-1: 3.2500 2018-2: 3.0000 2019-1: 3.0000 2019-2: 2.5000 2020-1: 3.0000 2020-2: 2.7500 2021-1: 2.5000 2021-2: 2.7500 2022-1: 3.0000 2022-2: 2.5000 2023-1: 2.5000
问题原因与解决方法
核心问题
你当前的代码没有实现加权平均,只是对每个Period下的Rating值做了普通算术平均:
- 代码中
period_ratings.mean()是把该Period下所有分组的Rating值(每个分组对应一个Rating)直接求平均,完全忽略了Count列的权重(即每个分组的样本数量)。 - 以2023-1周期为例,假设对应Rating值为[4.0,2.0,1.0,3.0],普通算术平均为
(4+2+1+3)/4=2.5,这正是Pandas返回的结果,和你需要的加权平均逻辑完全不符。
修正代码
要计算加权平均,需要用Count作为权重,公式为:加权平均值 = (Σ(Rating * Count)) / (ΣCount)
修改后的代码示例:
def create_bar_chart(df: pd.DataFrame, question: str): groups = df.groupby(['Period', question]).size().reset_index(name='Count') groups['Rating'] = groups.apply(lambda row: to_rating(question, row[question]), axis=1) groups['Rating'] = groups['Rating'].astype(float) print(groups.dtypes) print(groups.tail(5)) # 按Period分组计算加权平均值 weighted_means = groups.groupby('Period').apply( lambda x: (x['Rating'] * x['Count']).sum() / x['Count'].sum() ) # 遍历输出结果 for period, mean_rating in weighted_means.items(): print(f'{period}: {mean_rating:.4f}') # matplotlib code...
这样计算后,2023-1周期的结果会和你手动计算的2.7一致。
内容的提问来源于stack exchange,提问作者Asger Skov Velling
相关产品推荐
相关产品推荐

