Numpy中.sum()为何比.any()和.max()更快
在本文中,我们将介绍为什么在使用Numpy中,.sum()的速度比其他一些常用函数如.any()和.max()更快。
阅读更多:Numpy 教程
Numpy数组操作
Numpy是一种Python中用于科学计算的非常流行的库。Numpy中的一个重要部分就是它的数组功能。这些数组支持快速且高效的操作,包括求和、比较、条件求和、排序等。
下面是一个简单的例子,展示了如何创建一个Numpy数组,并对它进行一些简单的操作。
import numpy as np
# 创建一个二维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 求和
arr_sum = arr.sum() # 输出 21
# 求每行求和
row_sums = arr.sum(axis=1) # 输出 [6, 15]
# 求每列求和
col_sums = arr.sum(axis=0) # 输出 [5, 7, 9]
在上面的代码中,我们首先创建了一个二维Numpy数组。然后,使用.sum()函数计算了整个数组的总和,使用.sum(axis=1)求出每行的值和,使用.sum(axis=0)求出每列的和。这些函数都是非常常见的Numpy操作,我们将在接下来的章节中详细讨论它们的实现。
.any()与.max()的实现方式
和.sum()类似,.any()和.max()也是Numpy中非常常见的数组操作:
- .any()函数检查数组中是否至少存在一个True值,如果存在则返回True,否则返回False。
- .max()函数计算数组中的最大值。
下面是这些函数的代码实现:
def any(a, axis=None, out=None, keepdims=np._NoValue):
return umr_any(a, axis, out, keepdims)
def max(a, axis=None, out=None, keepdims=False, initial=_NoValue, where=True):
return umr_maximum(a, axis, None, out, keepdims, initial, where)
我们可以看到,两个函数都是直接调用底层的Numpy函数实现的,因此它们的速度问题主要来自这些底层函数的实现方式。
.sum()的实现方式
与.any()和.max()不同,.sum()的实现方式比较特殊,它使用的是Numpy中广泛使用的方法,叫做“内存连续性”。
内存连续性是指数组数据在内存中存储方式的一种特殊形式。在内存连续的数组中,元素在内存所有存储位置上的地址是连续的。这里的“内存”指的是计算机的RAM,而连续性部分是由操作系统和硬件来管理。
内存连续的数组有以下特点:
- 如果数组中的元素在内存中连续存储,那么CPU缓存将被充分利用,从而提升访问性能。
- 内存连续数组的创建和操作速度非常快。
在使用.sum()函数时,Numpy通过利用这些优点来提升性能:它使用了内存连续性的性质,从而减少了访问RAM的次数并提高了速度。
.any()和.max()的性能问题
回到我们最初的问题,为什么.sum()比其他常用函数如.any()和.max()更快?我们可以发现,.any()和.max()的实现方式使用了底层的Numpy函数,而不是利用内存连续性这种高效的方式。
因此,.any()和.max()在处理大型数组时可能会比.sum()慢,因为需要频繁访问数组的应用程序工作和学习的人带来不必要的麻烦。
此外,对于非内存连续的数组,.any()和.max()的运行时间会更长,因为它们必须使用更慢的算法来处理这些数组。
性能比较
为了验证这个想法,我们可以编写一个简单的比较代码来测试不同函数的速度。以下代码测试了对于一个随机生成的1000 x 1000的数组,.sum()、.any()、.max()三个函数的运行时间:
import numpy as np
import time
arr = np.random.randint(low=0, high=2, size=(1000, 1000))
start_time = time.time()
sum_res = arr.sum()
print("sum time: ", time.time() - start_time)
start_time = time.time()
any_res = arr.any()
print("any time: ", time.time() - start_time)
start_time = time.time()
max_res = arr.max()
print("max time: ", time.time() - start_time)
在我的电脑上,以上代码运行时间分别为:
- sum time: 0.00023698806762695312
- any time: 0.007611989974975586
- max time: 0.004670143127441406
可以看到,.sum()的运行时间非常快,而.any()和.max()的运行时间则慢了近20-30倍。
总结
综上所述,对于Numpy中的数组操作,.sum()的速度通常比其他常用函数如.any()和.max()更快。这主要是由于.sum()函数利用了内存连续性这一高效的数组存储方法,而其他函数则使用了底层的Numpy函数实现。在处理大型数组时,使用.sum()函数可以提高程序的运行效率,减少访问RAM的次数并提高速度。
极客教程