Pandas 随机填充DataFrame空值时出现周期性KeyError问题求解
报错原因
- 核心问题是你向
random.choice传入了带原始索引的pandas Series对象,而非普通列表:
你筛选非异常值的语句column_name[column_name != nan]返回的是保留原始行索引的Series,它的索引不是连续的0~n-1的整数。random.choice内部会生成一个范围在[0, len(筛选后的Series)-1]的随机整数,直接用这个整数作为下标取Series的值,但pandas的Series[整数]默认是按标签索引取值,而非按位置取值,当这个随机数刚好不是现有标签时,就会抛出KeyError。
因为取值是随机的,所以报错的索引值每次都不一样,重启后随机结果不同,就会出现报错偶现的情况。
解决方案
方案1:快速修复现有函数
只需要把筛选后的Series转成普通列表,random.choice就会按位置取值,不会触发索引问题:
import random def nan_fill_random(column_name, nan_val): # 先把非异常值提取为列表,避免索引问题 valid_values = column_name[column_name != nan_val].tolist() for i in range(len(column_name)): if column_name.iloc[i] == nan_val: # 用iloc按位置赋值,兼容原Series索引不连续的场景 column_name.iloc[i] = random.choice(valid_values)
注意:这里把参数名从nan改成了nan_val,避免和pandas的nan对象重名引发歧义
方案2:更高效的pandas原生实现(推荐)
你原来的循环写法在数据量较大时效率极低,用pandas内置方法可以百倍提升运行速度,同时自动保留原有值的分布权重:
import pandas as pd def nan_fill_random(column: pd.Series, nan_val) -> pd.Series: # 提取所有有效值 valid = column[column != nan_val] # 生成和待填充空值数量一致的随机样本,replace=True允许重复抽取 fill_vals = valid.sample(n=column.isin([nan_val]).sum(), replace=True) # 对齐索引后完成空值填充 column.loc[column == nan_val] = fill_vals.values return column # 调用方式 data['education'] = nan_fill_random(data['education'], 'unknown')
如果需要固定随机结果可给sample方法加random_state=自定义整数参数
内容的提问来源于stack exchange,提问作者Alexander Goldian
相关产品推荐
相关产品推荐

