You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas rolling apply嵌套迭代函数报OSError及月度执行需求求助

Pandas Rolling Apply 嵌套函数报错及月末执行解决方案

一、OSError: could not get source code 错误修复

问题根源

你的cal_sigma_A函数内部嵌套了iterative_sigma,而Pandas的rolling.apply()在处理这类嵌套函数时,无法正确提取内部函数的源码(尤其是自动启用numba优化时),从而触发该错误。

修复方案:拆分嵌套函数

把内部迭代函数独立出来,避免嵌套结构,同时修正原代码中收敛条件的逻辑错误:

import numpy as np
from scipy.stats import norm

# 独立迭代函数,避免嵌套
def iterative_sigma(x, sig, Va):
    d1 = (np.log(Va / x.Xt) + (x.rf + 0.5 * (sig ** 2))) / sig
    d2 = d1 - sig
    d1 = norm.cdf(d1)
    d2 = norm.cdf(d2)
    new_Va = (x.Ve + x.Xt * np.exp(-x.rf) * d2) / d1
    new_sigma = np.std(new_Va)
    
    # 修正收敛条件:用绝对值判断,避免单边条件导致无限递归
    if abs(new_sigma - sig) < 1e-4:
        return new_sigma
    # 防止无限递归的边界判断
    if np.isclose(new_sigma, sig):
        return new_sigma
    return iterative_sigma(x, new_sigma, new_Va)

def cal_sigma_A(x):
    ite_sig = x.sigma_E.iloc[-1]
    ite_Va = x.Ve
    return iterative_sigma(x, ite_sig, ite_Va)

调用时的额外优化

调用rolling.apply()时,直接传入函数名而非lambda,同时指定engine='python'强制禁用numba优化,避免源码获取问题:

merged.set_index('date').groupby(['gvkey','PERMNO'], group_keys=False).rolling('365D').apply(cal_sigma_A, engine='python')

二、仅在每月月末执行计算

方法1:筛选月末行后计算(效率更高)

先标记月末日期,仅对这些行执行rolling计算,其余行填充NaN:

import pandas as pd

# 确保date列为datetime类型
merged['date'] = pd.to_datetime(merged['date'])
merged = merged.set_index('date')

# 标记是否为当月最后一天
merged['is_month_end'] = merged.index.is_month_end

# 分组后仅对月末行计算
def apply_month_end_only(group):
    rolling_result = group.rolling('365D').apply(cal_sigma_A, engine='python')
    # 非月末行设为NaN
    rolling_result[~group['is_month_end']] = np.nan
    return rolling_result

final_output = merged.groupby(['gvkey','PERMNO'], group_keys=False).apply(apply_month_end_only)

方法2:在函数内判断月末(代码更简洁)

在cal_sigma_A中检查窗口最后一行是否为月末,非月末直接返回NaN:

def cal_sigma_A(x):
    # 仅在月末执行计算
    if not x.index[-1].is_month_end:
        return np.nan
    ite_sig = x.sigma_E.iloc[-1]
    ite_Va = x.Ve
    return iterative_sigma(x, ite_sig, ite_Va)

# 直接调用即可,非月末行自动返回NaN
final_output = merged.set_index('date').groupby(['gvkey','PERMNO'], group_keys=False).rolling('365D').apply(cal_sigma_A, engine='python')

内容的提问来源于stack exchange,提问作者Chen Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:15:26