您能否解释以下行为:
rows = pd.DataFrame([
(0, np.nan, np.nan, 'toto'),
(1, np.nan, np.nan, 'tata')
])
dico = {}
for row in rows.itertuples():
k = (row[2], row[3])
v = row[4]
print('hash(k) : {0}'.format(hash(k)))
v_prev = dico.setdefault(k, None)
if v_prev is None:
dico[k] = v
print('dico : {0}'.format(dico))
结果:
hash(k) : 3713080549408328131
hash(k) : 3713080549408328131
dico : {(nan, nan): 'toto', (nan, nan): 'tata'}
我设法使用相同的键(np.nan, np.nan)
创建一个dict。我只对np.nan
有这种行为。使用None
或其他任何内容,只需一个密钥即可获得通常的结果。
答案 0 :(得分:1)
可能有帮助的是np.nan == np.nan
是错误的。
因此,正在发生的事情是你的字典应该散列你的密钥,然后意识到它落在现有密钥上,最后将它与之前的密钥进行比较。由于它不相等 - 因为nan
不等于nan
- 它应该将它存储在另一个地方以避免碰撞。
但我无法解释原因
d = {}
d[(np.nan, np.nan)] = 3
d[(np.nan, np.nan)] = 5
print(d)
呈现{(nan, nan): 5}
答案 1 :(得分:0)
这是由于DataFrame投射到numpy.float64
。
np.float64('nan')
的行为与np.nan
或None
不同。
因此np.float64('nan') is np.float64('nan')
为False
而np.nan is np.nan
为True
,因为它是存储在numpy模块中的一个唯一的nan。
为了避免碰撞,dict检查密钥是否相同并使用is
opérator