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

Pandas的to_dict方法如何处理np.nan与None作为字典键的问题?

Pandas生成含重复NaN键字典的原因解析

先看你遇到的代码现象:

初始代码:

import pandas as pd
import numpy as np

a = {np.nan: -1, None: 1}

查看a的结果:

{nan: -1, None: 1}

将其转换为Series再转回字典:

pd.Series(a).to_dict()

你看到的结果:

{nan: -1, nan: 1}

但手动创建类似字典时,会直接覆盖重复键:

b = {np.nan: -1, np.nan: 1}

查看b的结果:

{nan: 1}

你还发现能给Pandas生成的字典继续添加np.nan键,但手动字典做不到,下面解释这背后的逻辑:

核心原因

1. Pandas对None的自动转换

当用{np.nan: -1, None: 1}创建Series时,Pandas会自动把None转换为np.nan,所以Series的索引最终是两个np.nan。虽然np.nan == np.nan返回False,但所有np.nan的哈希值是相同的。

2. Python字典的键判定规则

Python字典靠哈希值和相等性判断键是否重复。哪怕np.nan之间不相等,只要哈希值一致,就会被视为同一个键,后续的键值对会直接覆盖前面的。

3. 关于“重复键”的误解

你看到的{nan: -1, nan: 1}其实是显示层面的误导——要么是运行环境的特殊输出格式,要么是误读了结果。实际上pd.Series(a).to_dict()返回的是标准Python字典,里面只会保留最后一个np.nan对应的值(也就是1)。

4. 手动字典的覆盖逻辑

手动写{np.nan: -1, np.nan: 1}时,Python在解析字典字面量的阶段就会处理重复键,直接用后面的值覆盖前面的,所以最终只剩{nan: 1}。

验证代码

运行以下代码可以确认上述结论:

import pandas as pd
import numpy as np

a = {np.nan: -1, None: 1}
s = pd.Series(a)
print("Series内容:")
print(s)
# 输出:
# NaN   -1
# NaN    1
# dtype: int64

d = s.to_dict()
print("\n转换后的字典实际内容:")
print(d)
# 实际输出:{nan: 1}

print("\n访问字典中的nan键:")
print(d[np.nan])
# 输出:1

# 尝试添加新的nan键
d[np.nan] = 3
print("\n添加后的字典:")
print(d)
# 输出:{nan: 3}

替代方案(保留所有键值对)

如果需要保留所有重复NaN索引对应的键值对,可以用列表存储元组,或者用defaultdict存多值:

# 用列表存储所有键值对
key_value_pairs = list(zip(s.index, s.values))
print(key_value_pairs)
# 输出:[(nan, -1), (nan, 1)]

# 用defaultdict存储同一键的多个值
from collections import defaultdict
dd = defaultdict(list)
for k, v in zip(s.index, s.values):
    dd[k].append(v)
print(dd)
# 输出:defaultdict(list, {nan: [-1, 1]})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 23:25:27