当涉及到数值运算时,NumPy数组在效率方面通常优于Python提供的容器。NumPy是Python中用于科学计算的核心库之一,它提供了高效的多维数组对象和一系列函数用于数组操作。在这篇博客中,我们将讨论NumPy数组相对于Python提供的容器的优势,并举例说明其在数值运算方面的效率。
1. 内存布局
NumPy数组在内存中以连续的块存储数据,这使得对数组的访问更加高效。相比之下,Python提供的容器(如列表)存储的是对象的引用,而非对象本身的值,这可能导致内存碎片化和额外的访问开销。
2. 矢量化操作
NumPy提供了丰富的矢量化操作,这意味着可以在整个数组上执行相同的操作,而无需编写显式的循环。这样的操作利用了底层优化,避免了Python解释器的开销,从而提高了运算速度。
3. 广播
NumPy的广播功能允许对不同形状的数组进行算术运算,而无需进行显式的形状转换或循环。这简化了代码,并且可以避免复制数据,提高了运算效率。
4. 底层优化
NumPy的底层实现是用C语言编写的,其中包含了许多优化的算法和数据结构。这些优化使得NumPy在数值计算方面的性能比纯Python代码更高。
示例:通过对一维数组分别进行平方和三次方后进行相加,分别比较使用numpy数组和纯python进行操作的时间差
代码片段1:定义两个实现相应功能的函数
# 以纯python代码实现
def pythonSum(n):
# 这里有个注意点,range产生的是一个可迭代的对象,而不是一个可修改的对象
a=range(n)
b=range(n)
c=[]
for i in range(len(a)):
c.append(a[i]**2+b[i]**3)
return c
d=pythonSum(3)
print(d)
# 以Numpy实现
import numpy as np
def numpySum(n):
# numpy的矢量化操作:在整个数组上进行相同的操作,无需for循环
a=np.arange(n)
b=np.arange(n)
c=a**2+b**3
return c
e=numpySum(3)
print(e)
代码片段2:使用matplotlib绘制折线图进行对比,数据集为80000-90000,之间对应的arange数组
from datetime import datetime
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置中文显示字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
def timeDiff(n):
ptd=[]
ntd=[]
for i in n:
start=datetime.now()
pythonSum(i)
end=datetime.now()
ptd.append((end-start).total_seconds())
# print("python时间差为:",(end-start).total_seconds())
start=datetime.now()
numpySum(i)
end=datetime.now()
ntd.append((end-start).total_seconds())
# print("Numpy时间差为:",(end-start).total_seconds())
return ptd,ntd
n=[x*100 for x in range(800,900)]
# n=range(1000,5000)
pyTimeDiff,npTimeDiff=timeDiff(n)
plt.plot(n,pyTimeDiff,label="python")
plt.plot(n,npTimeDiff,label="numpy")
plt.xlabel("数据量")
plt.ylabel("时间差")
plt.title("Comparison of time difference between Python and numpy ")
plt.legend()
plt.show()
效果展示: