如何基于DataFrame的counter分段计算f变量的区间平均值?
按counter分段计算f的平均值解决方案
问题背景
你需要在pandas DataFrame中,以counter=1为分段起点,到下一个counter=1出现前为分段终点,计算每一段f的平均值。你的样例数据和期望输出已经很清晰,不过你尝试的自定义求和函数没能达到效果,咱们来一步步解决这个问题。
你的原始数据
f counter 0 49.798 1 1 49.797 2 2 49.793 3 3 49.792 4 4 49.794 5 5 50.203 1 6 50.201 1 7 50.201 2 8 50.202 1 9 50.205 2 10 50.206 3 11 50.209 4 12 50.210 5 13 50.212 6 14 50.210 7 15 50.211 8 16 50.211 9 17 50.211 10 18 50.212 11 19 50.210 12 20 50.206 13 21 50.205 14 22 50.206 15 23 50.201 16
期望输出
Average 0 49.79480 1 50.20300 2 50.20100 3 50.20794
你尝试的无效代码
def sum_f(x): global total if counter == 1: total == f return int(total) if counter == 1: total == f return int(total) else: total =+ f return int(total)
解决方案
其实这个需求用pandas的分组功能就能完美解决,不需要复杂的自定义函数,核心思路是用counter=1的出现次数作为分组标识,具体步骤如下:
1. 生成分组标识
首先,我们先给每一段数据打上分组标签:每次遇到counter=1,就开启一个新的分组。可以用布尔序列的累加求和来实现:
import pandas as pd # 先构造你的DataFrame(如果已经有了就跳过这一步) df = pd.DataFrame({ 'f': [49.798,49.797,49.793,49.792,49.794,50.203,50.201,50.201,50.202,50.205,50.206,50.209,50.21,50.212,50.21,50.211,50.211,50.211,50.212,50.21,50.206,50.205,50.206,50.201], 'counter': [1,2,3,4,5,1,1,2,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] }) # 创建分组键:每次counter=1时,组号自动+1 df['group'] = (df['counter'] == 1).cumsum()
执行后,df['group']会生成这样的序列:[1,1,1,1,1,2,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],完美对应了我们需要的分段。
2. 分组计算平均值
有了分组标签后,直接按group分组,对f列求平均即可:
# 计算每组的平均值,并整理成你需要的格式 average_df = df.groupby('group')['f'].mean().reset_index(name='Average') # 只保留Average列输出 print(average_df[['Average']])
运行结果
执行后得到的结果和你的期望完全一致:
Average 0 49.79480 1 50.20300 2 50.20100 3 50.20794
为什么你的原代码无效?
顺便说下你之前代码的几个问题,避免以后踩坑:
- 全局变量风险:用
global total在pandas的apply中很容易出问题,因为apply是逐行执行,全局变量的状态很难控制 - 语法错误:
total == f是比较运算符,不是赋值,应该用total = f;total =+ f应该是total += f(累加赋值) - 逻辑冗余:重复写了两次
if counter == 1的判断,没有意义 - 精度丢失:最后返回
int(total)会把浮点数转成整数,直接丢失了小数部分的精度
用pandas原生的分组功能不仅代码简洁,运行效率也比自定义函数高很多,还能避免这些低级错误。
内容的提问来源于stack exchange,提问作者Turtle Rocket
相关产品推荐
相关产品推荐

