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

Pandas如何在列值为NaN时跨列计算填充并解决KeyError

Pandas列值为NaN时按其他列计算填充及KeyError修复

问题背景

DataFrame的tags列存储字典类型数据,需从中提取lanes(车道数,全量行有值)、width(道路宽度,仅部分行有值)两个字段,要求width为空值时,按车道数 * 2.4的规则计算填充,运行自定义apply函数时触发KeyError: 'width'报错。

复现代码

初始字段提取代码

import pandas as pd
import numpy as np

data = {'tags': [{'access': 'private', 'highway': 'service', 
'is_in': 'Bellville Campus, Cape Peninsula University of Technology, Bellville, Western Cape, South Africa', 
'lanes': '2', 'maxheight': '3.3', 'maxspeed': '30', 'name': 'Engineering Way'}]}

df = pd.DataFrame(data)
df['lanes'] = df['tags'].apply(lambda x: x.get('lanes'))
df['width'] = df['tags'].apply(lambda x: x.get('width'))

类型转换与测试代码

# 原代码存在笔误:误将df写为rd
df['lanes'] = pd.to_numeric(df['lanes'])
df['width'] = pd.to_numeric(df['width'])
print(df)

测试输出:

tags  lanes  width
0  {'access': 'private', 'highway': 'service', 'i...      2    NaN

报错的自定义填充代码

def calc_width(row):
    if np.isnan(row['width']):
        """空值时按车道数计算宽度"""
        return row['lanes'] * 2.4

df['width'] = df.apply(calc_width)

运行后报错栈:

Traceback (most recent call last):
  Input In [49] in <cell line: 11>
    df['width'] = df.apply(calc_width)
  File ~\miniconda3\envs\osm3D_vc-env\lib\site-packages\pandas\core\frame.py:8839 in apply
    return op.apply().__finalize__(self, method="apply")
  File ~\miniconda3\envs\osm3D_vc-env\lib\site-packages\pandas\core\apply.py:727 in apply
    return self.apply_standard()
  File ~\miniconda3\envs\osm3D_vc-env\lib\site-packages\pandas\core\apply.py:851 in apply_standard
    results, res_index = self.apply_series_generator()
  File ~\miniconda3\envs\osm3D_vc-env\lib\site-packages\pandas\core\apply.py:867 in apply_series_generator
    results[i] = self.f(v)
  Input In [47] in calc_width
    if np.isnan(row['width']):
  File ~\miniconda3\envs\osm3D_vc-env\lib\site-packages\pandas\core\series.py:958 in __getitem__
    return self._get_value(key)
  File ~\miniconda3\envs\osm3D_vc-env\lib\site-packages\pandas\core\series.py:1069 in _get_value
    loc = self.index.get_loc(label)
  File ~\miniconda3\envs\osm3D_vc-env\lib\site-packages\pandas\core\indexes\range.py:389 in get_loc
    raise KeyError(key)
KeyError: 'width'

报错原因

  • df.apply()默认参数axis=0,按列遍历DataFrame,传入自定义函数的参数是整列的Series对象,不是行数据。遍历到非width列时,Series索引中不存在width键,直接触发KeyError。
  • 自定义函数缺失非空值分支:就算修正遍历方向,原有width非空的行也会因为没有返回值被填充为None。
  • 类型转换代码存在笔误:误将DataFrame变量名df写为rd,运行时会触发NameError。

修复方案

方案1:向量化填充(推荐,性能远高于apply)

不需要自定义遍历函数,直接用pandas内置方法实现,代码简洁运行效率高:

# 修正笔误完成类型转换
df['lanes'] = pd.to_numeric(df['lanes'])
df['width'] = pd.to_numeric(df['width'])

# 用lanes列计算值填充width的空值
df['width'] = df['width'].fillna(df['lanes'] * 2.4)

方案2:修正apply参数与函数逻辑

如果需要使用自定义函数处理更复杂的计算逻辑,需指定axis=1让apply按行遍历,同时补全非空值返回逻辑:

def calc_width(row):
    if pd.isna(row['width']):
        return row['lanes'] * 2.4
    # 非空时直接返回原有宽度值
    return row['width']

# 指定axis=1按行传入数据
df['width'] = df.apply(calc_width, axis=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:09:14