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

Agu*_*guy 26 python numpy

你能帮助理解native int类型和numpy.int32或numpy.int64类型之间的主要区别(如果有的话)是什么?

The*_*Cat 16

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

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

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

话虽这么说,numpy实际上能够制作python整数数组.但是它不是包含值的数组,而是包含对包含实际python整数的其他内存块的引用的数组.这不能以同样的方式来加速,这样即使所有的蟒蛇整数适合固定整数尺寸范围内,它仍然不会加速.

Python 2中没有这种情况.在Python 2中,Python整数是固定整数,因此可以直接转换为numpy整数.对于可变长度的整数,Python 2具有long类型.但是,这是混乱的,并决定这种混乱是不值得的性能提升,特别是当谁需要表现的人将使用numpy的或类似的东西反正.


hpa*_*ulj 13

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

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

In [1277]: x=123; y=np.int32(123)
Run Code Online (Sandbox Code Playgroud)

int 方法和属性:

In [1278]: x.<tab>
x.bit_length   x.denominator  x.imag         x.numerator    x.to_bytes
x.conjugate    x.from_bytes   x.real         
Run Code Online (Sandbox Code Playgroud)

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__     
Run Code Online (Sandbox Code Playgroud)

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   
Run Code Online (Sandbox Code Playgroud)

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__
Run Code Online (Sandbox Code Playgroud)

y在很多方面与0d数组相同.不一样,但很接近.

In [1281]: z=np.array(123,dtype=np.int32)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我必须用来item删除所有的numpy包装.

In [1303]: type(A[1].item())
Out[1303]: int
Run Code Online (Sandbox Code Playgroud)

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

A = np.array([1,123,0], np.int32)
Run Code Online (Sandbox Code Playgroud)

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

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')
Run Code Online (Sandbox Code Playgroud)

只有当我索引单个元素时才能得到一个np.int32对象.

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


mgi*_*son 5

我认为最大的区别是 numpy 类型与其 C 对应类型兼容。一方面,这意味着 numpy 整数可能会溢出......

>>> np.int32(2**32)
0
Run Code Online (Sandbox Code Playgroud)

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

>>> sys.getsizeof(1)
24
Run Code Online (Sandbox Code Playgroud)

Anp.int32并不更小:

>>> sys.getsizeof(np.int32(1))
28
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为 24​​ 几乎是任何 python 对象的开销。28 是因为我们需要构造一个 python 对象并在其中插入一个 c 整数 - 我认为(尽管我可能是错的 - 我不是 numpy 开发人员或其他任何人)。然而,当你将大量 c 整数打包到 numpy 数组中时,你只需要 1 个 python 对象来存储所有这些整数。 (4认同)
  • 您能详细说明“24”和“28”尺寸吗? (2认同)