如何从含nan的Pandas DataFrame通过to_dict获取与原字典一致的结果?
Pandas to_dict()返回字典中NaN值的本质与测试解决方案
我用包含float("nan")的字典构建了Pandas DataFrame,调用.to_dict()方法后得到的字典和原字典表现出差异——其中的NaN值无法通过常规相等判断匹配。想知道这个新的NaN究竟是什么,同时这个问题也给我用unittest.TestCase.assertEqual编写测试带来了困扰。
以下是测试示例代码:
import numpy as np import pandas as pd a_dict = { "a": (1, 2), "b": (3, float("nan")), } df = pd.DataFrame(a_dict) print(df.to_dict()) # {'a': {0: 1, 1: 2}, 'b': {0: 3.0, 1: nan}} # to_dict()得到的字典和原字典比较结果为False: print(a_dict == a_dict) # True print(df.to_dict() == a_dict) # False print(df.to_dict()["b"][1]) # nan print(type(df.to_dict()["b"][1])) # <class 'float'> print(df.to_dict()["b"][1] == float("nan")) # False print(df.to_dict()["b"][1] == np.nan) # False print(df.to_dict()["b"][1] == pd.NA) # False print(df.to_dict()["b"][1] is None) # False print(np.isnan(df.to_dict()["b"][1])) # True print(pd.isna(df.to_dict()["b"][1])) # True
问题解析
这个to_dict()返回的NaN本质上就是标准浮点型NaN,属于float类型,和你最初输入的float("nan")是同一类型的NaN。之所以所有==比较都返回False,是因为IEEE 754浮点数标准的规定:NaN和任何值(包括它自己)的相等比较结果都是False。
Pandas在处理输入的NaN时,会统一存储为标准浮点NaN,调用to_dict()后输出的就是这个值。你看到的"差异"其实只是NaN的固有比较特性导致的,而非值本身存在不同。
测试解决方案
在unittest中直接用assertEqual比较包含NaN的字典会失败,因为它会逐值用==判断。可以用以下两种方法解决:
- 使用Pandas提供的专用断言函数:
pd.testing.assert_dict_equal,它会正确识别NaN的相等性,示例:pd.testing.assert_dict_equal(df.to_dict(), expected_dict) - 自定义比较逻辑:遍历字典的键值对,遇到值时先用
pd.isna()判断是否为NaN,若是则验证两边都是NaN;否则再用==比较。
内容的提问来源于stack exchange,提问作者Tal Galili
相关产品推荐
相关产品推荐

