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

Pandas按列apply调用自定义函数返回指定索引DataFrame报错排查

报错原因
  • pandas中DataFrame.apply(axis=0)是逐列传入数据,lambda接收到的参数是整列的Series对象,不是列名字符串。
  • 你把长度154、值为1-8随机数的Series作为列索引传给.loc,pandas会尝试在列名里匹配这154个整数,自然找不到对应列,直接触发KeyError。
修复方案

方案1:修正apply传参逻辑

只需要在lambda中取传入列Series的.name属性,就能拿到真正的列名字符串,原有函数逻辑不需要做任何修改:

import numpy as np
import pandas as pd

# --------------- 原有数据构造 ---------------
frame_exposure = {
    'Canada': np.random.randint(1,9,154),
    'USA': np.random.randint(1,9,154),
    'Mexico': np.random.randint(1,9,154),
}
df_exposure = pd.DataFrame(frame_exposure,index=np.arange(1960,2114))

frame_expectancy = {
    'Canada': np.random.randint(60,80,61),
    'USA': np.random.randint(60,80,61),
    'Mexico': np.random.randint(60,80,61),
}
df_life_expectancy = pd.DataFrame(frame_expectancy,index=np.arange(1960,2021))

# --------------- 原有计算函数 ---------------
def calc_life_exposure(
    df_exposure,
    df_life_expectancy,
    col,
):
    exposure_birthyears_percountry = np.empty(len(df_life_expectancy))
    for i, birth_year in enumerate(df_life_expectancy.index):
        life_expectancy = df_life_expectancy.loc[birth_year,col] 
        death_year = birth_year + np.floor(life_expectancy)
        exposure_birthyears_percountry[i] = df_exposure.loc[birth_year:death_year,col].sum()
        exposure_birthyears_percountry[i] = exposure_birthyears_percountry[i] + \
            df_exposure.loc[death_year+1,col].sum() * \
                (life_expectancy - np.floor(life_expectancy))
    exposure_birthyears_percountry = pd.Series(
        exposure_birthyears_percountry,
        index=df_life_expectancy.index,
        name=col,
    )
    return exposure_birthyears_percountry

# --------------- 修正后的调用代码 ---------------
df_test = df_exposure.apply(
    lambda col_series: calc_life_exposure(
        df_exposure,
        df_life_expectancy,
        col_series.name,  # 取Series对应的真实列名
    ),
    axis=0,
)

运行后得到的df_test形状和df_life_expectancy完全一致:行索引为1960-2020年,列对应三个国家,符合预期。

方案2:直接拼接单列计算结果(可读性更高)

如果不想记apply的传参规则,可以直接遍历列名计算每个国家的结果,再拼接为完整DataFrame,逻辑更直白不容易出错:

df_test = pd.concat(
    [calc_life_exposure(df_exposure, df_life_expectancy, col) for col in df_exposure.columns],
    axis=1
)
注意事项

你提供的示例代码中用np.random.randint生成预期寿命数据,输出全为整数,因此函数里计算最后不满整年的部分暴露量的逻辑永远返回0。如果需要验证这部分逻辑,可以把预期寿命的生成代码替换为随机浮点数实现:

frame_expectancy = {
    'Canada': np.random.uniform(60,80,61),
    'USA': np.random.uniform(60,80,61),
    'Mexico': np.random.uniform(60,80,61),
}

内容的提问来源于stack exchange,提问作者Luke Grant

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:39:23