简体   繁体   English

python与numpy移位

[英]python bit shifting with numpy

I'm working with 64 bit unsigned integers and after bit shifting comparing the value before decoding the rest of the bit values. 我正在使用64位无符号整数,并且在对位进行了移位后比较了该值,然后再解码其余的位值。 I'm iterating over millions of values and trying to minimize process time. 我正在遍历数百万个值,并试图减少处理时间。

The issue is bit shifting is not supported with uint64 nor numpy-uint64. 问题是uint64或numpy-uint64不支持移位。 I'm trying to avoid using int64 to avoid negative values. 我试图避免使用int64来避免出现负值。

example data: 0x8204000000000080 after shifting(word>> 60): =-8 #but comparing to 0x8 示例数据:移位后(word >> 60)为0x8204000000000080:= -8#但与0x8比较

looping one million times and seeing how long it takes it was found that of all methods the '>>' shift operator was the most expedient with the next best option to call the abs() function. 循环一百万次并查看需要花费多长时间,发现在所有方法中,“ >>”移位运算符是最方便的,其次是调用abs()函数的最佳选择。 Is there a better more expedient solution for this? 是否有更好,更方便的解决方案?

Loop code: 循环码:

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)

Output: 输出:

2.055999994277954
3.1540000438690186
0.619999885559082
0.5810000896453857

The issue is that when you apply the shift to an array scalar, NumPy tries to produce an output type that can hold all values of both input dtypes (with a Python int cast to either int32 or int64). 问题是,当您将偏移应用于数组标量时,NumPy尝试生成可容纳两个输入dtype的所有值的输出类型(将Python int强制转换为int32或int64)。 There is no integer dtype that can hold all values of both uint64 and a signed dtype, and floats aren't an option here. 没有可以容纳uint64和带符号dtype的所有值的整数dtype,并且在这里不是浮点数的选择。

When one operand is an array and the other is a scalar (here a Python int), NumPy attempts to stuff the scalar into a smaller dtype , which for most shift operations means the shift amount is cast to int8 or uint8, depending on whether the other operand is signed. 当一个操作数是数组而另一个是标量(此处为Python int)时, NumPy尝试将标量填充为较小的dtype ,对于大多数移位操作,这意味着将移位量强制转换为int8或uint8,具体取决于其他操作数已签名。 uint64 and uint8 both fit in uint64. uint64和uint8都适合uint64。

You'll have to cast the shift amount to an 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
>>> 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)

I dont understand the problem perhaps? 我可能不明白这个问题?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM