NumPy 是 Numerical Python 的简称,它是目前 Python 数值计算中最为重要的基础包。大多数计算包都提供了基于 NumPy 的科学函数功能,将 NumPy 的数组对象作为数据交换的媒介。Numpy 之所以如此快,具有以下原因:
1. 底层实现
- C 和 Fortran 语言:NumPy 的核心是用 C 和 Fortran 编写的,这些语言的执行速度远快于 Python。NumPy 利用这些语言的高效性来实现数组操作和数学计算。
2. 数组的连续内存布局
- 内存效率:NumPy 数组在内存中是连续存储的,这使得 CPU 在访问数据时能够利用缓存,提高了数据访问速度。
- 避免 Python 的对象开销:与 Python 列表相比,NumPy 数组存储数据的方式更为紧凑,减少了每个元素的内存开销。
3. 向量化操作
- 批量处理:NumPy 支持向量化操作,允许用户对整个数组进行操作,而不是逐个元素处理。这种批量处理减少了 Python 的循环开销,显著提高了性能。
- 使用 SIMD 指令:NumPy 可以利用现代 CPU 的 SIMD(单指令多数据)指令集,进一步加速数组运算。
4. 广播机制
- 灵活性与效率:NumPy 的广播机制允许不同形状的数组进行运算,避免了不必要的复制和内存分配。这使得在处理不同维度数据时,仍然能够高效计算。
5. 丰富的数学函数库
- 优化的数学函数:NumPy 提供了大量优化过的数学函数,这些函数在底层实现上进行了性能优化,能够高效处理各种数学运算。
6. 并行计算
- 多线程支持:在某些情况下,NumPy 可以利用多线程来并行处理数据,充分利用多核 CPU 的计算能力。
我们可以使用 CPU time 和 wall time 来衡量程序执行时间:
- CPU Time:指的是程序在 CPU 上实际消耗的时间。它只计算 CPU 处理任务的时间,不包括等待 I/O 操作、上下文切换或其他系统操作的时间;
- Wall Time:指从程序开始到结束所经过的实际时间,也称为“实际时间”或“墙钟时间”。它包括了 CPU 执行时间、I/O 等待时间、以及程序在等待其他资源时的时间;
下面的例子将展现 NumPy 的效率之快,我们将其与 list 进行对比。假设一个 NumPy 数组包含 100 万个整数,还有一个同样数据内容的 Python 列表:
import numpy as np
my_arr = np.arange(1000000)
my_list = list(range(1000000))
%time for _ in range(10): my_arr2 = my_arr * 2
# Output:
# CPU times: total: 15.6 ms
# Wall time: 16.6 ms
%time for _ in range(10): my_list2 = [x * 2 for x in my_list]
# Output:
# CPU times: total: 609 ms
# Wall time: 618 ms
NumPy 的方法比 Python 的列表方法要快 10 到 100 倍,并且使用的内存也更少。
如果你喜欢本文,欢迎点赞,并且关注我们的微信公众号:Python技术极客,我们会持续更新分享 Python 开发编程、数据分析、数据挖掘、AI 人工智能、网络爬虫等技术文章!让大家在Python 技术领域持续精进提升,成为更好的自己!
添加作者微信(coder_0101),拉你进入行业技术交流群,进行技术交流~