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

引言

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

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

什么是向量化?

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

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

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

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.15 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.007 Seconds

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

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()
前 5 行数据快照标题

我们将新增一个名为 ‘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)
### 105 Seconds

使用向量化

start = time.time()
df["ratio"] = 100 * (df["d"] / df["c"])

end = time.time()
print(end - start)
### 0.13 seconds

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

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)
### 耗时: 166 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.26007707237825133 sec

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

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

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

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

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

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

创建数据集

import numpy as np
# 设置m的初始值 
m = np.random.rand(1,5)

# 500万行的输入值
x = np.random.rand(5000000,5)

使用循环

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")
####计算时间 = 26.219 seconds

使用向量化

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倍。

总结

在 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

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术狂潮AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值