如何用Pandas实现基于前一行数据计算s列的算法?
如何在Pandas DataFrame中实现递推计算s列?
首先,你要实现的逻辑很明确:
- 当
Tenure == 0时,s = 1 - 其他行的
s等于前一行的s值乘以(1 - 前一行的h值)
你之前写的函数没达到效果,核心问题在于apply的使用方式不对——apply默认是逐行/逐列独立处理,你的函数里的x每次调用都会重置为0,而且没有办法保留上一行的计算结果,自然没法完成递推。
你的原始数据(整理后):
popt stopt popcum h s Tenure 0 0.0 2383 508.0 5067890 0.000100 1 1 1.0 18358 17310.0 5065507 0.003417 0 2 2.0 16742 15103.0 5047149 0.002992 0 3 3.0 13298 11361.0 5030407 0.002258 0 4 4.0 9566 9522.0 5017109 0.001898 0
方法1:直观的循环实现(适合小数据集)
这种方式最容易理解,直接按顺序遍历每一行,用上一行的结果计算当前行:
# 先给Tenure=0的行设置初始s值 result3.loc[result3['Tenure'] == 0, 's'] = 1 # 从第二行开始递推 for i in range(1, len(result3)): # 获取上一行的s和h prev_s = result3['s'].iloc[i-1] prev_h = result3['h'].iloc[i-1] # 计算当前行的s result3['s'].iloc[i] = prev_s * (1 - prev_h)
方法2:向量化累乘实现(适合大数据集,速度更快)
你的递推逻辑可以转化为累乘运算:
s[0] = 1s[1] = s[0] * (1 - h[0])s[2] = s[1] * (1 - h[1]) = 1 * (1-h[0]) * (1-h[1])- ...
s[n] = 累乘从h[0]到h[n-1]的(1-h)值
用Pandas的cumprod()(累积乘积)可以高效实现:
# 构造(1-h)的序列,把第一行的前向移位值填充为1(因为s[0]不需要乘任何值) shifted_terms = (1 - result3['h']).shift(1).fillna(1) # 计算累积乘积得到s列 result3['s'] = shifted_terms.cumprod()
这段代码会自动处理初始值,而且比循环快很多,尤其是当你的DataFrame有几万甚至几十万行的时候。
为什么你之前的函数无效?
你的funkcyjka函数存在两个关键问题:
- 每次调用函数时,
x都会被重置为0,所以永远只计算第一行的s*(1-h),根本没有递推过程。 apply传入的res是单行的Series,不是整个DataFrame,所以res["s"].iloc[x]这种写法逻辑错误——你没法通过单行数据获取上一行的值。
内容的提问来源于stack exchange,提问作者Szejm
相关产品推荐
相关产品推荐

