python位移numpy

kam*_*tor 1 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)
Run Code Online (Sandbox Code Playgroud)

输出:

2.055999994277954
3.1540000438690186
0.619999885559082
0.5810000896453857
Run Code Online (Sandbox Code Playgroud)

use*_*ica 8

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

当一个操作数是一个数组而另一个是标量(这里是一个Python int)时,NumPy会尝试将标量填充到一个较小的dtype中,对于大多数移位操作,这意味着移位量被转换为int8或uint8,具体取决于是否其他操作数已签名.uint64和uint8都适合uint64.

您必须将移位金额转换为unsigned 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
Run Code Online (Sandbox Code Playgroud)