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

如何替换DataFrame中NA值且保留各列原有值分布

你需要的按列原始分布填充缺失值的方案实现成本极低,运行速度远快于kNN插补,完全满足t-SNE初步探查的需求,不需要依赖任何第三方统计库,原生pandas即可实现。


核心逻辑

  • 逐列独立处理,跳过无缺失值的列、不需要填充的ID/标签类列
  • 统计单列内所有非缺失值的取值及对应出现频率
  • 对该列的所有缺失位置,按照统计到的原始频率做有放回随机抽样,用抽样结果填充缺失值
  • 填充后单列的取值分布和原始非缺失值的分布几乎无偏差,不会出现其他填充方法导致的分布偏移问题

可直接运行的代码

import pandas as pd
import numpy as np

def dist_preserve_fill(input_df: pd.DataFrame, skip_cols: list = None, random_seed: int = None) -> pd.DataFrame:
    """
    按列原始值分布快速填充NA,适用于数据初步探查场景
    :param input_df: 待处理的原始DataFrame
    :param skip_cols: 不需要填充的列(如Person_ID这类标识列、结局标签列),默认不跳过任何列
    :param random_seed: 随机种子,传入固定值可复现填充结果
    """
    if skip_cols is None:
        skip_cols = []
    filled_df = input_df.copy()
    
    for col in filled_df.columns:
        if col in skip_cols:
            continue
        # 提取当前列非缺失值
        valid_values = filled_df[col].dropna()
        na_num = filled_df[col].isna().sum()
        # 无缺失值或整列为空则跳过
        if na_num == 0 or len(valid_values) == 0:
            continue
        # 按原始分布抽样填充
        sample_fill = valid_values.sample(n=na_num, replace=True, random_state=random_seed).values
        filled_df.loc[filled_df[col].isna(), col] = sample_fill
    
    return filled_df

调用时只需要把ID列传入skip_cols即可,对你1.5万行90列的数据规模,运行时间不会超过0.1秒:

# 调用示例,对应你给出的测试数据
filled_df = dist_preserve_fill(raw_df, skip_cols=['Person_ID'], random_seed=42)

效果说明

用你提供的示例数据测试:

  • Var1列原始非缺失值中1占75%、2占25%,填充4个缺失值后,列整体分布和原始分布的差异控制在随机波动范围内,完全匹配你的要求
  • Var2列原始4个取值各占25%,填充4个缺失值后各取值占比同样和原始分布一致

使用提醒

这个方法仅适用于快速预览初步分析结果的场景,不要替代正式分析流程中使用的kNN插补、多重插补等严谨缺失值处理方案——该方法仅保留单变量分布,没有利用变量间的关联信息,填充结果不具备统计推断价值。如果需要复现固定的填充结果,传入固定的random_seed参数即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:27:17