NumPy 位运算(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言

在数据科学和高性能计算领域,NumPy 作为 Python 的核心数值计算库,提供了丰富的数组操作功能。其中,NumPy 位运算是一类基于二进制位级操作的工具,能够高效处理整数类型的数组元素。无论是优化算法逻辑、实现低级数据操作,还是在图像处理、密码学等领域,位运算都扮演着重要角色。本文将从基础概念出发,结合实例代码,逐步解析 NumPy 位运算的核心功能与应用场景,帮助读者掌握这一工具的使用方法与优势。


基础概念:什么是位运算?

位运算(Bitwise Operations)是对二进制数的每一位进行操作的运算方式。每个整数在计算机中以二进制形式存储,例如数字 6 的二进制表示为 110。通过位运算,我们可以直接操作这些二进制位,例如:

  • 按位与(AND):仅当两个位均为 1 时结果为 1
  • 按位或(OR):只要有一个位为 1,结果即为 1
  • 按位异或(XOR):仅当两个位不同时结果为 1
  • 按位取反(NOT):将二进制位的 01 取反

比喻:可以将位运算想象为电路中的逻辑门。例如,按位与(AND)类似于“开关串联”,只有所有开关都闭合时,电路才会导通;而按位或(OR)则类似于“开关并联”,只要有一个开关闭合,电路就会导通。


NumPy 中的位运算函数

NumPy 提供了专为数组设计的位运算函数,这些函数在处理大规模数据时具有显著的效率优势。以下是核心函数及其用法:

1. 按位与(bitwise_and)

功能:对两个数组的对应元素执行按位与操作。
语法numpy.bitwise_and(x1, x2, out=None, ...)

示例

import numpy as np  

a = np.array([6, 12])  # 二进制:110, 1100  
b = np.array([3, 8])   # 二进制:011, 1000  
result = np.bitwise_and(a, b)  
print(result)  # 输出:[2 8]  

2. 按位或(bitwise_or)

功能:对两个数组的对应元素执行按位或操作。
语法numpy.bitwise_or(x1, x2, out=None, ...)

示例

a = np.array([1, 5])  # 0001, 0101  
b = np.array([3, 7])  # 0011, 0111  
result = np.bitwise_or(a, b)  
print(result)  # 输出:[3 7]  

3. 按位异或(bitwise_xor)

功能:对两个数组的对应元素执行按位异或操作。
语法numpy.bitwise_xor(x1, x2, out=None, ...)

示例

a = np.array([4, 9])  # 100, 1001  
b = np.array([3, 6])  # 011, 0110  
result = np.bitwise_xor(a, b)  
print(result)  # 输出:[7 15]  

4. 按位取反(invert)

功能:对单个数组的元素执行按位取反操作。
语法numpy.invert(x, out=None, ...)

示例

a = np.array([5, 10])  # 二进制:0101, 1010(假设为8位整数)  
result = np.invert(a)  
print(result)  # 输出:[-6 -11]  

位移操作:左移与右移

位移运算通过移动二进制位的位置实现快速乘除操作:

  • 左移(<<):将二进制位向左移动,低位补 0,相当于乘以 2^n
  • 右移(>>):将二进制位向右移动,高位补符号位(对于负数),相当于除以 2^n

NumPy 中的实现
虽然 NumPy 没有直接提供位移函数,但可以通过 np.left_shiftnp.right_shift 实现:

a = np.array([3, 8])  # 二进制:11, 1000  
result_left = np.left_shift(a, 1)  # 左移1位 → 6(110), 16(10000)  
result_right = np.right_shift(a, 1)  # 右移1位 → 1(1), 4(100)  
print(result_left)   # 输出:[ 6 16]  
print(result_right)  # 输出:[1 4]  

实际应用案例

案例1:提取二进制位中的特定信息

假设需要从图像的像素值中提取颜色通道:

pixel_values = np.array([0xFF0000, 0x00FF00, 0x0000FF], dtype=np.uint32)  
red_channel = np.bitwise_and(pixel_values, 0xFF0000)  # 提取红色部分  
print(hex(red_channel[0]))  # 输出:0xff0000  

案例2:高效实现掩码操作

在数据处理中,位运算可快速生成掩码数组:

data = np.array([15, 3, 7, 12])  
mask = np.bitwise_and(data, 8)  # 检查第4位是否为1  
print(mask)  # 输出:[8 0 0 8] → 15(1111)和12(1100)的第4位为1  

性能对比:NumPy vs 纯 Python

与纯 Python 的循环相比,NumPy 的向量化位运算在处理大规模数据时效率更高。以下是一个简单对比:

import timeit  

def pure_python_bitwise(n):  
    arr = list(range(n))  
    result = []  
    for num in arr:  
        result.append(num & 3)  # 提取最后两位  
    return result  

def numpy_bitwise(n):  
    arr = np.arange(n)  
    return np.bitwise_and(arr, 3)  

n = 1000000  
print("Python 时间:", timeit.timeit(lambda: pure_python_bitwise(n), number=1))  
print("NumPy 时间:", timeit.timeit(lambda: numpy_bitwise(n), number=1))  

总结与扩展

通过本文,我们系统学习了 NumPy 位运算的核心函数、操作逻辑及实际应用。位运算的优势在于其底层直接操作二进制位的高效性,尤其在需要快速处理整数数据、优化算法逻辑或实现低级数据操作时,能够显著提升程序性能。

对于进阶开发者,可以进一步探索以下方向:

  1. 结合 布尔索引,利用位运算实现复杂的数据筛选条件;
  2. 在图像处理中,通过位运算操作像素值实现滤波或特征提取;
  3. 研究位运算在加密算法(如 XOR 加密)中的应用。

掌握 NumPy 位运算,不仅能提升代码的效率,更能打开面向底层优化与高性能计算的大门。希望本文能成为您探索这一领域的起点!

最新发布