当Pandas.DataFrame.to_dict有"nan"时,如何从它获得相同的dict



我有一个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的求值结果为Falsea_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

最新更新