如何用同列非NaN随机值填充DataFrame中的NaN值?
用同列随机非NaN值填充DataFrame缺失值
问题描述
我有一个包含NaN值的DataFrame,希望用同列中的随机非NaN值填充该列的NaN值(比如从Col1的非NaN值里随机选值填充Col1的缺失),DataFrame如下:
Col1 Col2 Col3 Col4 Col5 0 -0.671603 -0.792415 0.783922 NaN Blue 1 0.207720 NaN 0.996131 Tom Yellow 2 -0.892115 -1.282333 NaN Julia NaN 3 -0.315598 -2.371529 -1.959646 NaN Pink 4 NaN NaN -0.584636 NaN Orange 5 0.314736 -0.692732 -0.303951 Jim NaN 6 0.355121 NaN NaN NaN Red 7 NaN -1.900148 1.230828 Sophia NaN 8 -1.795468 0.490953 NaN Anne Blue 9 -0.678491 -0.087815 NaN NaN NaN 10 0.755714 0.550589 -0.702019 NaN Pink 11 0.951908 -0.529933 0.344544 Tobi Yellow 12 NaN 0.075340 -0.187669 Jon Red 13 NaN 0.314342 -0.936066 NaN Yellow 14 NaN 1.293355 0.098964 Peter Orange
我尝试了以下代码,但没有达到预期效果:
import numpy as np import pandas as pd num_nan= df[col_name].isna().sum() for n in len(range(num_nan)): #pick random value from e.g. col1 that's not NaN df[col_name] = df[col_name].where((pd.notnull(df)), None).sample(random_state= 1) #replace NaN-value in e.g. col1 with picked value df[col_name]= df.fillna('value')
解决方案
方法一:循环逐列处理(直观易调试)
import pandas as pd import numpy as np def fill_nan_with_random_col_vals(df): # 遍历每一列 for col in df.columns: # 获取当前列的所有非NaN值 non_nan_values = df[col].dropna().values # 如果该列全是NaN,跳过避免报错 if len(non_nan_values) == 0: continue # 定位当前列的NaN位置 nan_mask = df[col].isna() # 生成对应数量的随机采样值(允许重复选取) random_fills = np.random.choice(non_nan_values, size=nan_mask.sum(), replace=True) # 填充NaN df.loc[nan_mask, col] = random_fills return df # 调用函数处理(用copy避免修改原DataFrame) filled_df = fill_nan_with_random_col_vals(df.copy())
方法二:用apply简化代码(简洁高效)
import pandas as pd import numpy as np filled_df = df.apply( lambda col: col.fillna( np.random.choice(col.dropna(), size=col.isna().sum(), replace=True) ) if col.dropna().size > 0 else col )
代码说明
- 两种方法都是针对每列单独处理:提取该列非NaN值 → 根据NaN数量随机采样 → 填充到对应位置。
- 加入了全NaN列的判断,避免
np.random.choice因空数组报错。 - 方法一适合需要添加额外逻辑或调试的场景;方法二用一行代码完成,适合快速处理。
原代码问题分析
- 循环语法错误:
for n in len(range(num_nan))应该是for n in range(num_nan),但这种循环方式效率极低。 - 填充逻辑错误:
sample(random_state=1)和fillna('value')没有准确定位NaN位置,且用固定字符串'value'填充,不是随机采样的列值。
内容的提问来源于stack exchange,提问作者Slo Ri
相关产品推荐
相关产品推荐

