您能否帮助了解native int类型与numpy.int32或numpy.int64类型之间的主要区别(如果有)?
答案 0 :(得分:12)
有几个主要差异。首先是python整数是灵活大小的(至少在python 3.x中)。这意味着它们可以增长以适应任何数量的任何数量(当然,在内存限制内)。另一方面,numpy整数是固定大小的。这意味着它们可以容纳最大值。这由整数(int32
与int64
)中的字节数定义,更多字节包含更大的数字,以及数字是有符号还是无符号(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)接口时应该考虑到这一点。