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
答案 0 :(得分:2)
Python long
值与a
中保存的整数的类型不同。具体来说,Python long
值不限于32位或64位,而是可以占用任意数量的内存。
另一方面,NumPy会将a
创建为int32
或int64
整数值的数组。当你左移这个数组时,你会得到一个相同数据类型的数组。这个内存不足以容纳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)
给定您创建的数组a
,output
的元素将是整数。与Python本身不同,numpy darray中的整数具有固定大小,具有定义的最大值和最小值。
numpy通过减少整数长度64位(100 mod 64 == 36)的模数来达到给定值(2 ** 36
)。