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

如何用同列非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因空数组报错。
  • 方法一适合需要添加额外逻辑或调试的场景;方法二用一行代码完成,适合快速处理。

原代码问题分析

  1. 循环语法错误:for n in len(range(num_nan)) 应该是 for n in range(num_nan),但这种循环方式效率极低。
  2. 填充逻辑错误:sample(random_state=1) 和 fillna('value') 没有准确定位NaN位置,且用固定字符串'value'填充,不是随机采样的列值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:31:29