我有一个Pandas DataFrame,它是由带有nan的dict(例如:float("nan")
(构建的。当我在上面使用.to_dict
时,我得到了一个不同的dict——nan值是";否则";。
有可能知道这个新的nan值是什么吗?
这是我创建的一个玩具示例,以及我做的一系列检查:
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() gives a different dict:
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
就动机而言,当我尝试使用unittest.TestCase.assertEqual
创建测试时,这让我很痛苦
提前感谢。
相关但没有帮助:
- 如何检查NaN值
- Pandas单元测试:如何断言NaT和NaN值相等
正如您所说,to_dict((给出了一个不同的dict,但它与nan
值无关df.to_dict()
产生{'a': {0: 1, 1: 2}, 'b': {0: 3.0, 1: nan}}
而不是{'a': (1, 2), 'b': (3, nan)}
,因此它是不相等的。将a_dict
中的nan
替换为数字(例如4
(,并且df.to_dict == a_dict
仍将计算为False
,因此nan
不是您的问题。
我想指出的是,np.nan == np.nan
的求值结果为False
。a_dict == a_dict
计算为True
的事实是由于"相等"的定义:相等意味着两个字典都有相同的键,并且键引用相同的对象,或者如果相等。请参阅此处了解更多信息。
为了解决你最初的问题";如何从Pandas.DataFrame.to_dict中获取相同的dict"请看这里。dict中的元组和panda会自动设置数据类型,这会导致下面的代码失败,这是一件很痛苦的事情。
基本上你可以做
d = df.to_dict('list')
{i: tuple(d[i]) for i in d.keys()} == a_dict # True
这可能不是最好的方法,但这是检查仅测试的方法
import pandas as pd
import numpy as np
class custom_dict(dict):
def __eq__(self, __o: object) -> bool:
if isinstance(__o, dict):
return self.keys() == __o.keys() and all(list(self[k1]) in (list(__o[k1]),) for k1 in self.keys())
return False
a_dict = {
"a": (1, 2),
"b": (3, np.nan),
}
df = pd.DataFrame(a_dict, dtype=object)
print(df.to_dict('list',into=custom_dict))
print(a_dict)
print(df.to_dict('list', into=custom_dict)["b"][1] in (np.nan, )) # true
print(df.to_dict('list', into=custom_dict) == a_dict). # true