native int类型和numpy.int类型之间有什么区别?

时间:2016-07-01 23:34:58

标签: python numpy

您能否帮助了解native int类型与numpy.int32或numpy.int64类型之间的主要区别(如果有)?

4 个答案:

答案 0 :(得分:12)

有几个主要差异。首先是python整数是灵活大小的(至少在python 3.x中)。这意味着它们可以增长以适应任何数量的任何数量(当然,在内存限制内)。另一方面,numpy整数是固定大小的。这意味着它们可以容纳最大值。这由整数(int32int64)中的字节数定义,更多字节包含更大的数字,以及数字是有符号还是无符号(int32 vs 。uint32),无符号能够容纳更大的数字,但不能保留负数。

所以,您可能会问,为什么要使用固定大小的整数?原因是现代处理器具有内置工具,可以在固定大小的整数上进行数学运算,因此对它们的计算要快得多。实际上,当数字足够小时,python在幕后使用固定大小的整数,只有在数字太大时才切换到速度较慢,灵活大小的整数。

固定大小值的另一个优点是它们可以放在一致大小的相同类型的相邻内存块中。这是numpy数组用于存储数据的格式。 numpy所依赖的库能够以这种格式对数据进行极快的计算,实际上现代CPU具有加速这种计算的内置功能。对于可变大小的python整数,这种计算是不可能的,因为没有办法说明块应该有多大并且数据格式没有一致性。

话虽这么说,numpy实际上能够制作python整数数组。但是它不是包含值的数组,而是包含对包含实际python整数的其他内存块的引用的数组。这不能以相同的方式加速,因此即使所有python整数都适合固定的整数大小,它仍然不会加速。

Python 2中没有这种情况。在Python 2中,Python整数是固定整数,因此可以直接转换为numpy整数。对于可变长度的整数,Python 2具有long类型。但这令人困惑,并且决定这种混乱不值得获得性能提升,特别是当需要表现的人无论如何都会使用numpy或类似的东西时。

答案 1 :(得分:12)

另一种看待差异的方法是询问这两种对象有哪些方法。

在Ipython中,我可以使用tab complete来查看方法:

In [1277]: x=123; y=np.int32(123)

int方法和属性:

In [1278]: x.<tab>
x.bit_length   x.denominator  x.imag         x.numerator    x.to_bytes
x.conjugate    x.from_bytes   x.real         

int'运营商'

In [1278]: x.__<tab>
x.__abs__           x.__init__          x.__rlshift__
x.__add__           x.__int__           x.__rmod__
x.__and__           x.__invert__        x.__rmul__
x.__bool__          x.__le__            x.__ror__
...
x.__gt__            x.__reduce_ex__     x.__xor__
x.__hash__          x.__repr__          
x.__index__         x.__rfloordiv__     

np.int32方法和属性(或属性)。有些相同,但更多,基本上所有ndarray个:

In [1278]: y.<tab>
y.T             y.denominator   y.ndim          y.size
y.all           y.diagonal      y.newbyteorder  y.sort
y.any           y.dtype         y.nonzero       y.squeeze   
...
y.cumsum        y.min           y.setflags      
y.data          y.nbytes        y.shape   

y.__方法与int方法非常相似。他们可以做同样的数学运算。

In [1278]: y.__<tab>
y.__abs__              y.__getitem__          y.__reduce_ex__
y.__add__              y.__gt__               y.__repr__
...
y.__format__           y.__rand__             y.__subclasshook__
y.__ge__               y.__rdivmod__          y.__truediv__
y.__getattribute__     y.__reduce__           y.__xor__

y在许多方面与0d数组相同。不完全相同,但很接近。

In [1281]: z=np.array(123,dtype=np.int32)
当我索引该类型的数组时,

np.int32就是我得到的:

In [1300]: A=np.array([0,123,3])

In [1301]: A[1]
Out[1301]: 123

In [1302]: type(A[1])
Out[1302]: numpy.int32

我必须使用item删除所有numpy包装。

In [1303]: type(A[1].item())
Out[1303]: int

作为numpy用户,np.int32是带有int包装的numpy。或者相反,ndarray的单个元素。通常我不会注意A[0]是否给了我'本地'int或numpy等价物。与一些新用户相比,我很少使用np.int32(123);我会改用np.array(123)

A = np.array([1,123,0], np.int32)

不包含3个np.int32个对象。相反,它的数据缓冲区长3 * 4 = 12字节。这是数组开销,在1d中将其解释为3个整数。 view向我展示了具有不同解释的相同数据缓冲区:

In [1307]: A.view(np.int16)
Out[1307]: array([  1,   0, 123,   0,   0,   0], dtype=int16)

In [1310]: A.view('S4')
Out[1310]: array([b'\x01', b'{', b''],   dtype='|S4')

只有在我为单个元素编制索引时才会获得np.int32对象。

列表L=[1, 123, 0]不同;它是一个指针列表 - 指向内存中int个对象的指针。类似地,对于dtype =对象数组。

答案 2 :(得分:1)

我认为最大的区别是numpy类型与它们的C版本兼容。首先,这意味着numpy int会溢出......

>>> np.int32(2**32)
0

这就是为什么你可以创建一个整数数组并将数据类型指定为np.int32的原因。然后,Numpy会分配一个足够大的数组来保存指定数量的32位整数,然后当你需要这些值时,它会将C整数转换为np.int32(非常快)。能够从np.int32和C-int来回转换的好处还包括节省大量内存。 Python对象通常很大:

>>> sys.getsizeof(1)
24

np.int32并不小:

>>> sys.getsizeof(np.int32(1))
28

但是请记住,大部分时间我们使用numpy数组时,我们只使用C整数,只占用4个字节(而不是24个字节)。在处理数组中的标量值时,我们只需要使用np.int32

答案 3 :(得分:-2)

不是一个完整的答案,但这应该让你开始http://docs.scipy.org/doc/numpy-1.10.1/user/basics.types.html

  

有5种基本数字类型代表布尔值(bool),整数(int),无符号整数(uint)浮点(浮点数)和复数。名称中带有数字的那些表示该类型的位大小(即,需要多少位来表示存储器中的单个值)。某些类型(如int和intp)具有不同的位,取决于平台(例如32位与64位计算机)。在与处理原始内存的低级代码(例如C或Fortran)接口时应该考虑到这一点。