nan怎么用:一次说透
nan怎么用?别把它理解成一个要主动“使用”的普通值,它更像数据处理里的警示牌。我在清洗表格、写 pandas、排查模型报错时,通常按识别、统计、处理、验证四步走。方法不复杂,关键是别跳步。
我的结论:nan不是拿来算的,是拿来排查的
第一次认真处理 nan,是一份 20 多万行的订单表。金额列看着干净,模型训练却一直报错。最后发现有 417 行金额是 nan,来源是退款单没有原始支付金额。问题不大,但如果直接填 0,客单价会被拉低。
所以问 nan怎么用,我的答案很直接:用它定位数据断点,用合适方式补救,不要把它伪装成正常数字。
识别:别用等号,直接用工具函数
Python 里单个值可以用 math.isnan,但它只适合浮点数;NumPy 用 np.isnan;pandas 里最省心的是 pd.isna() 或 df.isna()。表格级别排查,我常用 df.isna().sum().sort_values(ascending=False)。
JavaScript 里用 Number.isNaN(x),不要写 x === NaN。SQL 里情况更复杂,不同数据库对 NaN 支持不一样,更多时候你会遇到 NULL。跨系统同步时,最好在数据字典里写清楚缺失值表示法。
统计:先看比例,再看分布
只知道有多少 nan 不够。10 万行里缺 100 行,和 1000 行里缺 100 行,不是一回事。我的习惯是同时看缺失数量和缺失率:missing_rate = df.isna().mean()。
更要看缺失是不是集中出现。比如某个渠道的手机号缺失率 60%,其他渠道只有 3%,这通常不是用户行为,而是渠道接口没传。处理 nan 前发现这个问题,价值比补值本身更大。
处理:删除、填补、插值,别一招走天下
删除适合缺失少、且行不关键的情况。填补适合需要保留样本的建模场景,数值列常用中位数,类别列可用“未知”。时间序列可以考虑插值,但别给断崖式业务数据硬插。
我很少直接用均值补所有列。均值怕极端值,补完还会让数据看起来过于平滑。用户收入、订单金额、停留时长这类偏态字段,中位数通常更稳。
验证:处理完一定要回头查
处理 nan 后,我会做三件事:再跑一次缺失统计;检查字段类型有没有变;抽样看 20 行原始值和处理后值。很多 bug 就藏在类型变化里,比如整数列因为 nan 被 pandas 读成 float。
结尾再压一句:nan怎么用,核心不是 fillna 写得多熟,而是知道每个 nan 为什么出现。来源说不清的补值,都是给后面埋雷。
常见问题
- nan怎么用 pandas 删除?
- 用 dropna。df.dropna() 会删除含 nan 的行;df.dropna(subset=['price']) 只看 price 列;如果想删除全为空的行,用 how='all'。
- nan怎么用 fillna 填充?
- df['age'].fillna(df['age'].median()) 可用中位数填年龄;类别列可用 fillna('未知')。填充前先确认缺失含义,别默认填0。
- nan处理后还要保留标记吗?
- 建模场景建议保留。可以加一列 age_missing = df['age'].isna().astype(int),再填补 age。缺失本身可能有预测价值。