错误的行为:基于元组的相同键的dict

时间:2015-12-08 18:39:12

标签: python numpy dictionary pandas

您能否解释以下行为:

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或其他任何内容,只需一个密钥即可获得通常的结果。

2 个答案:

答案 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.float64np.float64('nan')的行为与np.nanNone不同。 因此np.float64('nan') is np.float64('nan')Falsenp.nan is np.nanTrue,因为它是存储在numpy模块中的一个唯一的nan。

为了避免碰撞,dict检查密钥是否相同并使用isopérator