python位移numpy

时间:2015-05-28 17:52:15

标签: python numpy

我正在使用64位无符号整数,并在比特移位之后比较该值,然后解码其余的位值。 我正在迭代数百万个值并尝试最小化处理时间。

问题是uint64和numpy-uint64都不支持位移。我试图避免使用int64来避免负值。

示例数据: 0x8204000000000080 移位后(字>>> 60):= - 8#但与0x8相比

循环一百万次并查看它需要多长时间才发现所有方法中的'>>'移位运算符是最有效的,具有调用abs()函数的下一个最佳选项。对此有更好的解决方案吗?

循环代码:

import numpy as np
import time

start_time= time.time()
for i in range(1000000):
    x= np.int64(-1)
    x=np.right_shift(x,60)
print (time.time()-start_time)

start_time= time.time()
for i in range(1000000):
    x= np.uint64(-1)
    x=int(x/(2**60))
print (time.time()-start_time)

start_time= time.time()
for i in range(1000000):
    x= np.int64(-1)
    x=abs(x>>60)
print (time.time()-start_time)

start_time= time.time()
for i in range(1000000):
    x= np.int64(-1)
    x= x>>60
print (time.time()-start_time)

输出:

2.055999994277954
3.1540000438690186
0.619999885559082
0.5810000896453857

2 个答案:

答案 0 :(得分:6)

问题在于,当您将shift应用于数组标量时,NumPy会尝试生成一个输出类型,该输出类型可以保存两个输入dtypes的所有值(使用Python int强制转换为int32或int64)。没有整数dtype可以保存uint64和签名dtype的所有值,并且浮点数不是这里的选项。

当一个操作数是一个数组而另一个是标量(这里是一个Python int)时,NumPy attempts to stuff the scalar into a smaller dtype,对于大多数移位操作来说意味着移位量被转换为int8或uint8,具体取决于是否是另一个操作数签了。 uint64和uint8都适合uint64。

您必须将转移金额转换为无符号的int:

>>> numpy.uint64(-1) >> 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'right_shift' not supported for the input types, and the inputs
 could not be safely coerced to any supported types according to the casting rul
e ''safe''
>>> numpy.uint64(-1) >> numpy.uint64(1)
9223372036854775807

答案 1 :(得分:2)

>>> import numpy
>>> a = numpy.array([1,2,3],dtype=numpy.uint64)
>>> a>>2
array([0, 0, 0], dtype=uint64)

>>> a = numpy.array([1,2,2**64-1],dtype=numpy.uint64)
>>> a>>2 
array([0, 0, 4611686018427387903], dtype=uint64)
>>> a>>60
array([ 0,  0, 15], dtype=uint64)

我也许不明白这个问题?