NumPy 位运算 - NUMPY教程

NumPy 位运算

位运算是一种在二进制数字的位级别上进行操作的一类运算,它们直接操作二进制数字的各个位,而不考虑数字的整体值。

NumPy 提供了一系列位运算函数,允许对数组中的元素进行逐位操作,这些操作与 Python 的位运算符类似,但作用于 NumPy 数组,支持矢量化处理,性能更高。

位运算在计算机科学中广泛应用于优化和处理底层数据。

NumPy bitwise_ 开头的函数是位运算函数。

NumPy 位运算包括以下几个函数:

操作 函数/运算符 描述
按位与 numpy.bitwise_and(x1, x2) 对数组的每个元素执行逐位与操作。
按位或 numpy.bitwise_or(x1, x2) 对数组的每个元素执行逐位或操作。
按位异或 numpy.bitwise_xor(x1, x2) 对数组的每个元素执行逐位异或操作。
按位取反 numpy.invert(x) 对数组的每个元素执行逐位取反(按位非)。
左移 numpy.left_shift(x1, x2) 将数组的每个元素左移指定的位数。
右移 numpy.right_shift(x1, x2) 将数组的每个元素右移指定的位数。
示例代码
importnumpyasnparr1=np.array([True,False,True],dtype=bool)arr2=np.array([False,True,False],dtype=bool)result_and=np.bitwise_and(arr1,arr2)result_or=np.bitwise_or(arr1,arr2)result_xor=np.bitwise_xor(arr1,arr2)result_not=np.bitwise_not(arr1)print("AND:",result_and)# [False, False, False]print("OR:",result_or)# [True, True, True]print("XOR:",result_xor)# [True, True, True]print("NOT:",result_not)# [False, True, False]# 按位取反arr_invert=np.invert(np.array([1,2],dtype=np.int8))print("Invert:",arr_invert)# [-2, -3]# 左移位运算arr_left_shift=np.left_shift(5,2)print("Left Shift:",arr_left_shift)# 20# 右移位运算arr_right_shift=np.right_shift(10,1)print("Right Shift:",arr_right_shift)# 5

也可以使用 "&"、 "~"、 "|" 和 "^" 等操作符进行计算:

  1. 与运算(&): 对应位上的两个数字都为1时,结果为1;否则,结果为0。

    例如:1010 & 1100 = 1000

  2. 或运算(|): 对应位上的两个数字有一个为1时,结果为1;否则,结果为0。

    例如:1010 | 1100 = 1110

  3. 异或运算(^): 对应位上的两个数字相异时,结果为1;相同时,结果为0。

    例如:1010 ^ 1100 = 0110

  4. 取反运算(~): 对数字的每个位取反,即0变为1,1变为0。

    例如:~1010 = 0101

  5. 左移运算(<<): 将数字的所有位向左移动指定的位数,右侧用0填充。

    例如:1010 << 2 = 101000

  6. 右移运算(>>): 将数字的所有位向右移动指定的位数,左侧根据符号位或补零。

    例如:1010 >> 2 = 0010

bitwise_and

bitwise_and() 函数对数组中整数的二进制形式执行位与运算。

示例代码
importnumpyasnpprint('13 和 17 的二进制形式:')a,b=13,17print(bin(a),bin(b))print('\n')print('13 和 17 的位与:')print(np.bitwise_and(13,17))

输出结果为:

13 和 17 的二进制形式:

0b1101 0b10001





13 和 17 的位与:

1

以上实例可以用下表来说明:

1 1 0 1
AND
1 0 0 0 1
运算结果 0 0 0 0 1

位与操作运算规律如下:

A B AND
1 1 1
1 0 0
0 1 0
0 0 0

bitwise_or

bitwise_or()函数对数组中整数的二进制形式执行位或运算。

示例代码
importnumpyasnpa,b=13,17print('13 和 17 的二进制形式:')print(bin(a),bin(b))print('13 和 17 的位或:')print(np.bitwise_or(13,17))

输出结果为:

13 和 17 的二进制形式:

0b1101 0b10001

13 和 17 的位或:

29

以上实例可以用下表来说明:

1 1 0 1
OR
1 0 0 0 1
运算结果 1 1 1 0 1

位或操作运算规律如下:

A B OR
1 1 1
1 0 1
0 1 1
0 0 0

invert

invert() 函数对数组中整数进行位取反运算,即 0 变成 1,1 变成 0。

对于有符号整数,取该二进制数的补码,然后 +1。二进制数,最高位为0表示正数,最高位为 1 表示负数。

看看 ~1 的计算步骤:

  • 1 (这里叫:原码)转二进制 = 00000001
  • 按位取反 = 11111110
  • 发现符号位(即最高位)为 1 (表示负数),将除符号位之外的其他数字取反 = 10000001
  • 末位加1取其补码 = 10000010
  • 转换回十进制 = -2
  • 表达式 二进制值(2 的补数) 十进制值
    5 00000000 00000000 00000000 00000101 5
    ~5 11111111 11111111 11111111 11111010 -6
示例代码
importnumpyasnpprint('13 的位反转,其中 ndarray 的 dtype 是 uint8:')print(np.invert(np.array([13],dtype=np.uint8)))print('\n')# 比较 13 和 242 的二进制表示,我们发现了位的反转print('13 的二进制表示:')print(np.binary_repr(13,width=8))print('\n')print('242 的二进制表示:')print(np.binary_repr(242,width=8))

输出结果为:

13 的位反转,其中 ndarray 的 dtype 是 uint8:

[242]





13 的二进制表示:

00001101





242 的二进制表示:

11110010

left_shift

left_shift() 函数将数组元素的二进制形式向左移动到指定位置,右侧附加相等数量的 0。

示例代码
importnumpyasnpprint('将 10 左移两位:')print(np.left_shift(10,2))print('\n')print('10 的二进制表示:')print(np.binary_repr(10,width=8))print('\n')print('40 的二进制表示:')print(np.binary_repr(40,width=8))#  '00001010' 中的两位移动到了左边,并在右边添加了两个 0。

输出结果为:

将 10 左移两位:

40





10 的二进制表示:

00001010





40 的二进制表示:

00101000

right_shift

right_shift() 函数将数组元素的二进制形式向右移动到指定位置,左侧附加相等数量的 0。

示例代码
importnumpyasnpprint('将 40 右移两位:')print(np.right_shift(40,2))print('\n')print('40 的二进制表示:')print(np.binary_repr(40,width=8))print('\n')print('10 的二进制表示:')print(np.binary_repr(10,width=8))#  '00001010' 中的两位移动到了右边,并在左边添加了两个 0。

输出结果为:

将 40 右移两位:

10





40 的二进制表示:

00101000





10 的二进制表示:

00001010