【Python】疯狂的加速函数!

共 1693字,需浏览 4分钟

 ·

2022-02-12 13:20

作者:杰少

einsum函数


简介

在平时的工作中,包括时间序列等的建模中,我们常常会涉及到线性或者Multilinear代数的计算,很多时候包括我在内也喜欢偷懒使用numpy来处理,个人觉得还是可以的,但有的朋友觉得这个看起来可读性会差一些,并且速度上也差一些,今天就推荐一个新的函数einsum函数。

通过einsum函数,我们可以写出可读性更好,更加高效的函数。

einsum函数


01


关于einsum函数

einsum函数一般会用于向量,矩阵,张量的计算中。

如果输入的是标量(scalar),我们就可以空着,因为它没有下标。

02


einsum函数优势

1.速度优势

因为numpy很多是用C写的。

  • 如果我们使用Python循环时,所有数据操作都在Python解释器中进行。

  • 当使用内置numpy函数时,它发生在C中,这就是numpy速度更快的原因。

  • 使用einsum时,numpy会在C中处理数据一次并返回最终结果,而使用多个numpy函数会花费更多时间返回多个值。

2.可读性优势

einsum的代码可读性会更强,能大大提高代码的可读性和效率。

代码
  • 比较循环,numpy中的其它函数,einsum

从下面的案例中,我们发现einsum比numpy快乐将近30倍,比循环快了500-600倍。

import numpy as np

A = np.random.rand(1000,1000)
B = np.random.rand(1000,1000)
%%time
# Using loops
s = 0
n, m = A.shape
for i in range(n):
    for j in range(m):
        s += A[i, j]*B[i, j] 
s

# CPU times: user 596 ms, sys: 5.79 ms, total: 602 ms
# Wall time: 607 ms
# 249760.77497519302
CPU times: user 596 ms, sys: 5.79 ms, total: 602 ms
Wall time: 607 ms
249760.77497519302
%%time
# Using built-in numpy functions
np.trace(np.dot(A.T, B))

# CPU times: user 113 ms, sys: 8.54 ms, total: 121 ms
# Wall time: 38.1 ms
# 249760.7749751993
CPU times: user 113 ms, sys: 8.54 ms, total: 121 ms
Wall time: 38.1 ms
249760.7749751993
%%time
# Using einsum
np.einsum('ij,ij->', A,B)

# CPU times: user 1.64 ms, sys: 689 µs, total: 2.33 ms
# Wall time: 1.19 ms
# 249760.7749751993
CPU times: user 1.64 ms, sys: 689 µs, total: 2.33 ms
Wall time: 1.19 ms
249760.7749751993
适用问题

所有涉及到矩阵,向量,张量等计算的问题。

参考文献
  1. Write Better And Faster Python Using Einstein Notation
往期精彩回顾




浏览 42
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报