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

Pandas透视表新增Intl列后出现大量NaN值问题排查

问题诊断与解决方案

看起来你的问题大概率出在两个容易踩坑的环节:链式索引导致的更新未真正写入原数据,或者去重步骤意外过滤了有效条目,我们一步步拆解排查:

1. 先解决链式索引的隐形陷阱

你用来更新货币列的代码:

datagrouped['List Price Currency'][df['Price Book Name'].str.contains("International",na=False)] = 'Intl'

这是典型的链式索引操作(先取列再做行切片),Pandas通常会触发SettingWithCopyWarning(如果没关闭警告的话)。虽然你打印时看到值更新了,但实际上可能只是修改了datagrouped的临时视图,而非原DataFrame本身。后续对datagrouped做去重和透视时,原数据里的"Intl"值其实并没有真正被保存下来。

修复方案:改用.loc做安全赋值

替换成Pandas官方推荐的.loc索引方式,确保修改直接写入原数据:

# 先生成匹配国际价格本的掩码(注意要用datagrouped自身的列,避免索引不匹配)
mask = datagrouped['Price Book Name'].str.contains("International", na=False)
# 用.loc精准定位并修改
datagrouped.loc[mask, 'List Price Currency'] = 'Intl'

2. 检查去重步骤是否误删有效数据

你的去重代码:

df99 = datagrouped.drop_duplicates(['Product Code','List Price Currency'])

默认情况下drop_duplicates会保留每组重复组合的第一行。如果某个Product Code对应"Intl"的条目有多个,而恰好第一行的List Price是空值(NaN),那透视后就会出现NaN;或者某些有效"Intl"条目被意外当成重复项删除了。

验证与修复:

  • 先排查datagrouped中"Intl"行的价格是否为空:
# 筛选所有标记为Intl的行,查看空价格情况
intl_rows = datagrouped[datagrouped['List Price Currency'] == 'Intl']
print(intl_rows[intl_rows['List Price'].isna()])
  • 如果存在空值,先填充或删除无效行;如果没有空值,修改去重逻辑确保保留有效行:
# 先按价格排序,把空值放到最后,再保留每组最后一个非空行
df99 = datagrouped.sort_values('List Price', na_position='last')\
                  .drop_duplicates(['Product Code','List Price Currency'], keep='last')

3. 透视前的最后校验

在执行透视前,先确认df99里每个产品都包含所有4种货币的条目:

# 统计每个产品对应的货币种类数
currency_count = df99.groupby('Product Code')['List Price Currency'].nunique()
# 查看货币种类不足4种的产品
print(currency_count[currency_count < 4])

如果输出有结果,说明这些产品确实缺少对应货币的行,需要回到数据标记步骤,确认是否所有国际价格本的行都被正确标记为"Intl"。


按照这几个步骤排查,应该能解决透视后大量NaN的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:33:14