加速你的Python代码:向量化技术揭秘

picture.image点击上方蓝字关注我们

01引言

在编程世界里,循环操作我们并不会感到陌生,几乎所有的编程语言都会教会我们如何使用它。因此,一旦遇到需要重复执行的任务,默认我们就会想到用循环来解决。但是,当任务规模扩大到百万或十亿级别的迭代时,坚持使用循环简直是自讨苦吃。你可能会浪费几个小时,最终才发现这条路行不通。这正是为什么在 Python 中采用向量化技术至关重要的原因。

Python 向量化技术不仅大幅提升了代码执行效率,还极大地增强了代码的可读性和简洁性 。向量化技术让我们能够一次性处理整组数据,而不是逐个迭代,这在处理大规模数据集时尤为重要。从数据分析到机器学习模型的构建,向量化已经成为了提高性能的关键步骤。无论是在面对复杂算法还是日常编码实践中,向量化都显示出了其不可或缺的价值。通过优化和模块化设计,即使最初没有找到最优解,向量化也为后续性能提升提供了可能。这种技术不仅仅关乎速度,更关乎编程思维的转变——从传统逐步迭代到高效并行处理。随着技术的演进和应用场景的拓展,Python 向量化无疑将继续在数据科学领域扮演重要角色。

什么是向量化?

向量化(Vectorization)是一种执行数组操作的技术,它通过 NumPy 库加以实现。这个技术背后的原理是,它能够一次性对数组或序列中的所有元素进行操作处理,而不像‘for’循环那样逐行进行。

在不使用循环的情况下,向量化可以加快 Python 代码的速度。利用这样的方法可以有效地减少代码运行所需的时间。我们可以在 Python 中使用向量化来完成很多事情,例如缩放器乘法或点积乘法。

今天我们将探讨几个可以用向量化来替代 Python 循环的实例。这将帮助你在编程时节省宝贵时间,并提高编码技巧。

02

Example 1:求和运算

首先,让我们来看一个基础例子,在 Python 中如何使用循环和向量化来计算数字之和。

  • 使用循环

        
import time   
start = time.time()  
  
# 循环求和  
total = 0  
# 遍历150万数字  
for item in range(0, 1500000):  
    total = total + item  
  
print('sum is:' + str(total))  
end = time.time()  
print(end - start)  
#1124999250000  
#0.13 Seconds
    
  • 使用向量化

        
import numpy as np  
  
start = time.time()  
# 矢量化求和-使用numpy进行矢量化  
# np. arange 创建从0到1499999的数字序列  
print(np.sum(np.arange(1500000)))  
end = time.time()  
print(end - start)  
  
##1124999250000  
##0.006 Seconds
    

相比于使用 range 函数进行迭代,向量化的执行时间大约缩短了 18 倍。当处理 Pandas DataFrame 时,这种时间差异将更加明显。

03

Example 2:数学运算(应用于 DataFrame)

在数据科学领域,开发者处理 Pandas DataFrame 时经常用循环来创建新的派生列,并进行数学运算。

在下面的示例中,我们将展示如何轻松地用向量化技术替代循环来完成这类任务。

创建 DataFrame

DataFrame 是一种以行列形式组织的表格数据。

我们创建了一个包含 500 万行和 4 列的 pandas DataFrame,每个单元格填充了 0 到 50 之间的随机值。


        
import numpy as np  
import pandas as pd  
df = pd.DataFrame(np.random.randint(0, 50, size=(5000000, 4)), columns=('a','b','c','d'))  
df.shape  
# (5000000, 5)  
df.head()
    

picture.image

我们将新增一个名为 ‘ratio’ 的列,用来计算列 ‘d’ 和 ‘c’ 的比值。

  • 使用循环

        
import time   
start = time.time()  
  
# 使用iterrows遍历DataFrame  
for idx, row in df.iterrows():  
    # 创建新列   
    df.at[idx,'ratio'] = 100 * (row["d"] / row["c"])    
end = time.time()  
print(end - start)  
### 106 Seconds
    
  • 使用向量化

        
start = time.time()  
df["ratio"] = 100 * (df["d"] / df["c"])  
  
end = time.time()  
print(end - start)  
### 0.13 seconds
    

在 DataFrame 的操作中,我们可以看到显著的性能提升,使用向量化方法与传统 Python 循环相比, 执行速度几乎快了 1000 倍

04

Example 3:条件判断语句在数据框架上的运用

在编程时,我们经常会遇到需要使用条件判断 '如果-否则' 的场景。但在 Python 中,这些条件逻辑可以通过向量化操作来简化。

例如,在我们之前提到的第二个用例中创建的数据框架上,假设我们要根据列 ‘a’ 的条件来创建一个新的列 ‘e’。

  • 使用循环

        
import time   
start = time.time()  
  
# 使用iterrows遍历DataFrame  
for idx, row in df.iterrows():  
    if row.a == 0:  
        df.at[idx,'e'] = row.d      
    elif (row.a <= 25) & (row.a > 0):  
        df.at[idx,'e'] = (row.b)-(row.c)      
    else:  
        df.at[idx,'e'] = row.b + row.c  
end = time.time()  
print(end - start)  
### 耗时: 178 seconds
    
  • 使用向量化

        
# 使用向量化  
  
start = time.time()  
df['e'] = df['b'] + df['c']  
df.loc[df['a'] <= 25, 'e'] = df['b'] -df['c']  
df.loc[df['a']==0, 'e'] = df['d']end = time.time()  
print(end - start)  
## 0.26007707595825188 sec
    

传统方法下我们会用循环来完成这个任务,而向量化方法则可以大幅提升执行速度——经测试,速度提升了惊人的 600倍

05

Example 4(进阶):解决机器学习与深度学习网络问题

深度学习任务通常涉及到大量复杂的方程求解,这些方程可能需要对数百万甚至数十亿条数据进行计算。使用 Python 的循环来计算这些方程通常效率极低,而向量化则是解决这一问题的理想选择。

举个例子,在多元线性回归分析中,我们需要为数百万条数据计算出 y 的值:

picture.image

在这里,我们可以用向量化方法来替代传统的循环计算。

m1、m2、m3... 这些系数的值是通过解决上述方程,使用与 x1、x2、x3... 对应的数百万数据值计算得出的(为了简化问题,这里我们只讨论一个简单的乘法步骤)。

创建数据集


        
import numpy as np  
# 设置m的初始值   
m = np.random.rand(1,5)  
  
# 500万行的输入值  
x = np.random.rand(5000000,5)
    

picture.image

picture.image

  • 使用循环

        
import numpy as np  
m = np.random.rand(1,5)  
x = np.random.rand(5000000,5)  
  
total = 0  
tic = time.process_time()  
for i in range(0,5000000):  
    total = 0  
    for j in range(0,5):  
        total = total + x[i][j]*m[0][j]   
          
    zer[i] = total   
toc = time.process_time()  
print ("计算时间 = " + str((toc - tic)) + "seconds")  
####计算时间 = 25.237 seconds
    
  • 使用向量化

picture.image


        
tic = time.process_time()  
  
#点积  
np.dot(x,m.T)   
toc = time.process_time()  
print ("Computation time = " + str((toc - tic)) + "seconds")  
####计算时间 = 0.102 seconds
    

传统方法下我们会使用循环,而向量化方法则可以使用 np.dot 函数来实现矩阵乘法,其速度比传统循环快了165倍。

06

总结

在 Python 编程中,向量化不仅速度极快,而且在处理大型数据集时更加高效。

随着时间的推移,开始尝试向量化你的代码,你会逐渐习惯这种思维方式,并从中受益。

References

[1]. Linear algebra|Vectors and spaces:

https://www.khanacademy.org/math/linear-algebra

[2]. Vectorization in Python

https://www.javatpoint.com/vectorization-in-python

picture.image

如果你对这篇文章感兴趣,而且你想要了解更多关于AI 领域的实战技巧,可以

关注「技术狂潮AI」公众号

。在这里,你可以看到最新最热的AIGC 领域的干货文章和案例实战教程。

0
0
0
0
评论
未登录
暂无评论