使用numpy数组左移大1

时间:2014-12-10 11:41:10

标签: python arrays python-2.7 numpy bit-shift

Python确实可以通过大整数左移

1L << 100
# 1267650600228229401496703205376L

但NumPy似乎有问题:

a = np.array([1,2,100])
output = np.left_shift(1L,a)
print output 
# array([          2,           4, 68719476736])

有没有办法使用NumPy的left_shift操作来克服这个问题?单独访问数组元素会产生相同的错误结果:

1L << a[2]
# 68719476736

3 个答案:

答案 0 :(得分:2)

Python long值与a中保存的整数的类型不同。具体来说,Python long值不限于32位或64位,而是可以占用任意数量的内存。

另一方面,NumPy会将a创建为int32int64整数值的数组。当你左移这个数组时,你会得到一个相同数据类型的数组。这个内存不足以容纳1 << 100,并且左移的结果会溢出它在数组中分配的内存,从而产生不正确的结果。

要保持大的整数,您必须指定a以获得object数据类型。例如:

>>> np.left_shift(1, a.astype(object))
array([2, 4, 1267650600228229401496703205376L], dtype=object)

object数组可以包含不同类型的混合,包括无限大小的Python long /整数值。但是,使用object数组时,同构数据类型NumPy数组的许多性能优势将会丢失。

答案 1 :(得分:1)

这也是一个带有64位Python的issue,除了这个成为问题的整数更大。如果您运行a[2]=1L << a[2],您将获得此跟踪:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long

因为回溯说 Python int太大而无法转换为C long ,所以你需要将数组类型(实际上是C结构)更改为python对象:

>>> a = np.array([1,2,100],dtype='O')
>>> a[2]=1L << a[2]
>>> a
array([1, 2, 1267650600228229401496703205376L], dtype=object)

答案 2 :(得分:1)

给定您创建的数组aoutput的元素将是整数。与Python本身不同,numpy darray中的整数具有固定大小,具有定义的最大值和最小值。

numpy通过减少整数长度64位(100 mod 64 == 36)的模数来达到给定值(2 ** 36)。