为什么numpy.int32不被识别为int类型

时间:2018-01-26 09:13:26

标签: python numpy types

我只花了半个小时来研究statsmodels中的一个错误' SARIMAX功能,我终于可以追溯到numpy.int32失败的类型检查int的事实。

>>> import numpy as np
>>> foo = np.int32(3)
>>> isinstance(foo, int)
False

如果没有明确的类型转换,有没有办法绕过这种问题? 正确的代码是否应该测试类型而不检查变量是否可以安全地转换为类型?

编辑:我的问题由一个帐户回答,说明了这种行为的原因是什么技术限制或设计决定,以及如何python处理纯python的int和numpy {{1}可能会出现{或int32种类型。

2 个答案:

答案 0 :(得分:4)

为什么应该 numpy.int32来自intint是一个特定的类。它是表示整数的一种方式。这并不意味着每个表示整数的类都应该来自intnumpy.int32具有不同的语义和不同的方法 - 例如,它具有像0维数组一样运行所需的大部分功能 - 并且继承自int对于实现{{1}并不是特别有用}。

在Python 2的某些版本(仅限Windows?)上,numpy.int32实际上将从numpy.int32下降(在这些版本上也是32位),但我相信这个设计决定可以追溯到int执行环绕式算术(如int而不是在溢出时向numpy.int32提升,以及long不存在的时间。那时候这是一个更合理的决定。

至于operator.index numpy.int32如何处理intnumbers.Integral做了一些好工作,但实施依赖于人们明确地register使用{ {1}},人们通常不认为这样做。在引入numbers.Integral 6年后,NumPy在2014之前未添加register次来电。像SymPy这样的类似的库仍然没有调用。

我发现numbers.Integral是更好的检查:

operator.index

try: real_int = operator.index(some_intlike_thing) except TypeError: # Not intlike. do_something_about_that() 是一个类似于类的类必须实现的钩子,以使其实例可用作序列索引。这是一个比operator.index更严格的检查,它会接受int(x)3.5。如果缺少这个钩子会产生一个具体的,容易引起注意的影响,那么它比'3'支持更有可能存在。

答案 1 :(得分:3)

__mro__列出了类的继承堆栈:

np.int32.__mro__
Out[30]: 
(numpy.int32,
 numpy.signedinteger,
 numpy.integer,
 numpy.number,
 numpy.generic,
 object)

int.__mro__
Out[31]: (int, object)

对于基本数组:

x=np.array([1,2,3])    
x.dtype
Out[33]: dtype('int32')
此堆栈上的

isinstance个类返回True:

isinstance(x[0], np.int32)
Out[37]: True    
isinstance(x[0], np.number)
Out[38]: True    

int不在此堆栈中:

isinstance(x[0], int)
Out[39]: False    
isinstance(x[0], object)
Out[40]: True

itemnumpy包装器中提取值:

isinstance(x[0].item(), int)
Out[41]: True

@kazemakase建议使用numbers模块:

isinstance(x[0], numbers.Integral)
Out[47]: True