这是一个错误吗?不能简单地将 dict 键从 numpy 更改为原始数据类型
Is this a bug? Cannot simply change dict keys from numpy to primitive data types
我有一个由 pandas 生成的字典,它有 numpy.int64
个对象而不是本机 int
作为键。我需要将它们更改为本机类型,并且对为什么以下代码不是那么成功感到困惑:
d = {np.int64(0): None}
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
k_nat = k.item()
print(str(type(k_nat))) # <class 'int'>
print(d) # {0: None}
d.update({k_nat:1})
print(d) # {0: 1}
# Therefore update using int was successful
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
谁能解释一下这是怎么回事?从我的角度来看,这段代码自相矛盾,因为使用原语 k_nat
的更新是成功的,但最终密钥仍然是 numpy.int64
.
不,这不是错误。
这段代码表明密钥在更新期间没有改变:
import numpy as np
d = {np.int64(0): None}
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
k_nat = k.item()
print(str(type(k_nat))) # <class 'int'>
print(d) # {0: None}
d.update({k_nat:1})
print(d) # {0: 1}
# Therefore update using int was successful
# But key does not change
print(type(list(d.keys())[0])) # → <class 'numpy.int64'>
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
Python 对待 int(0)
和 np.int64(0)
w.r.t。 dict-access。但是原始键没有改变(只有值)。请注意,int(0)
和 np.int64(0)
在 print(d)
等表达式中都表示为 0
。所以他们 看起来 就像他们一样。但是,它们相等但不相同。
特别是我们有这种行为
print(d[np.int64(0)] == d[int(0)]) # True
print(np.int64(0) == int(0)) # True
print(np.int64(0) is int(0)) # False
如果要转换key-type,可以使用:
new_d = {int(k): v for k, v in d.items()}
print(type(list(new_d.keys())[0])) # <class 'int'>
对于 some 类 确实可以在不改变对象的 id
的情况下改变对象的类型,因此它仍然可以作为同样的 dict-key:
class A(object):
pass
class B(object):
pass
d = {A(): None}
print(type(list(d.keys())[0])) # <class '__main__.A'>
# change type of object but not the object itself
list(d.keys())[0].__class__ = B
print(type(list(d.keys())[0])) # <class '__main__.B'>
然而,对于其他类(包括np.int64
)这是不可能的:
x = np.int64(0)
try:
x.__class__ = int
except TypeError as err:
print(err) # __class__ assignment only supported for heap types or ModuleType subclasses
0
和 np.int64(0)
哈希到相同的值:
print(hash(0))
print(np.int64(0))
输出:
0
0
所以你的字典实际上并没有替换 keys 数据类型,你可以使用简单的字典理解来实现你想要的行为(在任何情况下修改一个可迭代的同时循环它可能不是一个好主意)
import numpy as np
d = {np.int64(0): None}
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
d = {int(k):v for k,v in d.items()}
print(d)
for k, v in d.items():
print(str(type(k)))
不过,根据您实际获取字典的方式,您最好直接更改 pandas series/dataframe
的数据类型
我有一个由 pandas 生成的字典,它有 numpy.int64
个对象而不是本机 int
作为键。我需要将它们更改为本机类型,并且对为什么以下代码不是那么成功感到困惑:
d = {np.int64(0): None}
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
k_nat = k.item()
print(str(type(k_nat))) # <class 'int'>
print(d) # {0: None}
d.update({k_nat:1})
print(d) # {0: 1}
# Therefore update using int was successful
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
谁能解释一下这是怎么回事?从我的角度来看,这段代码自相矛盾,因为使用原语 k_nat
的更新是成功的,但最终密钥仍然是 numpy.int64
.
不,这不是错误。
这段代码表明密钥在更新期间没有改变:
import numpy as np
d = {np.int64(0): None}
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
k_nat = k.item()
print(str(type(k_nat))) # <class 'int'>
print(d) # {0: None}
d.update({k_nat:1})
print(d) # {0: 1}
# Therefore update using int was successful
# But key does not change
print(type(list(d.keys())[0])) # → <class 'numpy.int64'>
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
Python 对待 int(0)
和 np.int64(0)
w.r.t。 dict-access。但是原始键没有改变(只有值)。请注意,int(0)
和 np.int64(0)
在 print(d)
等表达式中都表示为 0
。所以他们 看起来 就像他们一样。但是,它们相等但不相同。
特别是我们有这种行为
print(d[np.int64(0)] == d[int(0)]) # True
print(np.int64(0) == int(0)) # True
print(np.int64(0) is int(0)) # False
如果要转换key-type,可以使用:
new_d = {int(k): v for k, v in d.items()}
print(type(list(new_d.keys())[0])) # <class 'int'>
对于 some 类 确实可以在不改变对象的 id
的情况下改变对象的类型,因此它仍然可以作为同样的 dict-key:
class A(object):
pass
class B(object):
pass
d = {A(): None}
print(type(list(d.keys())[0])) # <class '__main__.A'>
# change type of object but not the object itself
list(d.keys())[0].__class__ = B
print(type(list(d.keys())[0])) # <class '__main__.B'>
然而,对于其他类(包括np.int64
)这是不可能的:
x = np.int64(0)
try:
x.__class__ = int
except TypeError as err:
print(err) # __class__ assignment only supported for heap types or ModuleType subclasses
0
和 np.int64(0)
哈希到相同的值:
print(hash(0))
print(np.int64(0))
输出:
0
0
所以你的字典实际上并没有替换 keys 数据类型,你可以使用简单的字典理解来实现你想要的行为(在任何情况下修改一个可迭代的同时循环它可能不是一个好主意)
import numpy as np
d = {np.int64(0): None}
for k, v in d.items():
print(str(type(k))) # <class 'numpy.int64'>
d = {int(k):v for k,v in d.items()}
print(d)
for k, v in d.items():
print(str(type(k)))
不过,根据您实际获取字典的方式,您最好直接更改 pandas series/dataframe
的数据类型