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

pandas中.loc可提取列值但.at获取单个值报KeyError的解决方法

问题成因
  • pandas的.at是严格基于行列标签做精确匹配的单值索引器,不会做隐式的位置推断、类型转换,匹配规则比.loc更严格,只要传入的标签不存在就会直接抛KeyError。
  • 这个报错的核心矛盾是:你打印loc[:,"each"]看到的行号14,并不是rsiDFEach本身实际存在的行标签。出现这个认知差的原因很明确:
    1. RSI指标计算规则决定了length=14时,需要至少15条有效价格数据才能产出第一个非NaN值,也就是计算返回的Series长度至少15,索引从0到14。
    2. 你用来生成rsiDFEach的原始数据prcAllExtractDF大概率之前做过行筛选、空值删除等操作但没有重置索引,导致rsiDFEach继承的行索引实际最大标签不到14;或者输入的价格序列本身长度不足15,pandas在给DataFrame赋值新列时按索引对齐自动截断了多余的计算结果,最终标签14根本没被写入rsiDFEach。
  • 从报错栈可以看到异常出在RangeIndex.get_loc方法,也印证了当前rsiDFEach的行索引是连续范围索引,14不在这个索引的合法取值范围内,你看到的打印输出是计算过程中临时Series的显示结果,不是最终DataFrame的真实索引。
解决方法

根据你的需求(提取单个值存入变量),选任意一种方案即可:

  • 方案1:重置索引后再用.at访问
    先把DataFrame的索引重置为从0开始的连续整数,丢弃旧的无效索引,保证行标签和你看到的行号完全一致:
    def generateRSIDF(prcAllExtractDF: pd.DataFrame):
        rsiAllColumn = np.zeros(0)
        for i in range(0,1):
            rsiDFEach = prcAllExtractDF.iloc[:,i].to_frame()
            # 重置索引,丢弃原索引
            rsiDFEach = rsiDFEach.reset_index(drop=True)
            rsiDFEach["each"] = pda.rsi(rsiDFEach.iloc[:,0], length=14)
            # 此时标签14真实存在,可正常访问
            target_val = rsiDFEach.at[14, "each"]
            print(target_val)
        return rsiAllColumn
    
  • 方案2:用按位置索引的.iat替代.at
    不需要关心行标签具体是什么,直接按数据所在的行列位置提取,适合你明确知道要取第N行数据的场景:
    # 先获取"each"列的位置索引
    each_col_idx = rsiDFEach.columns.get_loc("each")
    # 取第15行(位置索引从0开始,第15行对应位置14)的值
    target_val = rsiDFEach.iat[14, each_col_idx]
    
  • 方案3:直接从RSI计算结果的Series中取值
    把RSI计算结果存为临时变量,赋值给DataFrame列的同时直接从Series提取目标值,绕开DataFrame索引对齐的问题:
    def generateRSIDF(prcAllExtractDF: pd.DataFrame):
        rsiAllColumn = np.zeros(0)
        for i in range(0,1):
            price_series = prcAllExtractDF.iloc[:,i]
            rsi_series = pda.rsi(price_series, length=14)
            rsiDFEach = price_series.to_frame()
            rsiDFEach["each"] = rsi_series
            # 直接从计算好的RSI Series里取值
            target_val = rsi_series.iloc[14]
        return rsiAllColumn
    
  • 方案4:用.loc配合.item()提取标量
    如果不想改原有索引逻辑,用.loc定位到目标单元格后,调用.item()直接转成原生Python类型的标量值,兼容性比.at更好:
    # 先通过索引位置取到实际的行标签,再访问
    target_row_label = rsiDFEach.index[14]
    target_val = rsiDFEach.loc[target_row_label, "each"].item()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:01:19