将numpy.array向右旋转一位

时间:2017-03-25 02:02:35

标签: python arrays numpy bit-manipulation

我有一个numpy.array,并希望将其内容向右旋转一位。我希望尽可能高效地执行此操作(在执行速度方面)。另请注意,数组的每个元素都是一个8位数字(np.uint8)。旋转假定数组存储一个大数字,该大数字被分成大小为8比特的块,即,我不想自己旋转每个8比特元素,而是将整个数组一起旋转。

以下是一个消除任何混淆的示例:

a = numpy.array([0b00000000, 0b00000001])
# rotation should be performed globally
# i.e., the result should be
# rotate(a) == numpy.array([0b10000000, 0b00000000])

我是如何尝试解决问题的?

方法#1:将输入数组转换为二进制表示形式,并将元素的二进制字符串连接成一个大字符串。然后弹出最低有效位并将其插入最高位之前。最后,将大字符串切成8位块,将每个块转换为np.uint8,并将其存储在旋转结果的相应位置。我想这个解决方案是正确的,但效率不高,特别是如果输入数组很大的话。

方法#2:我发现很难用文字解释这个想法,所以我只是尝试使用下面的代码片段来传达它:

# Let w be the input array
# read the least significant bits of every element in w 
# and store them into another array lsb
mask = np.ones(shape=w.shape, dtype=np.int8)
lsb = np.bitwise_and(w,mask)
shiftedLsb = np.left_shift(np.roll(lsb, 1), 7)
rotW = np.right_shift(w,1) 
rotationResult = np.bitwise_or(shiftedLsb, rotw)

我的问题:在执行速度方面,有没有更好的方法来实现这种轮换?

谢谢大家。

1 个答案:

答案 0 :(得分:1)

您可以通过减少临时数据的内存分配来加速“方法#2”:

   function changetToX(input) {
     return input.substring(0, 3) + 'xxx.xxx-' + input.substring(input.length - 2);
    }

在我的系统上,使用1MB输入数组,这是原始速度的两倍,并产生相同的结果。

如果你愿意销毁输入,你可以消除其余两个分配中的一个(可能通过添加一个可选的def method2a(w): rotW = np.right_shift(w, 1) lsb = np.bitwise_and(w, 1) np.left_shift(lsb, 7, lsb) rotW[0] |= lsb[-1] rotW[1:] |= lsb[:-1] return rotW 参数,就像NumPy在例如out中所做的那样)。