performance - 如何向量化这个函数
问题描述
以下代码有效,但我想通过矢量化创建 Z。如何做到这一点?
import numpy as np
from numpy import sqrt
from math import fsum
points = np.array([[0,0],\
[5,-1],\
[4,6],\
[1,3]])
d = lambda x: fsum([sqrt((x[0]-z[0])**2 + (x[1]-z[1])**2) for z in points])
x = np.linspace(min(points[:,0]),max(points[:,0]),100)
y = np.linspace(min(points[:,1]),max(points[:,1]),100)
X, Y = np.meshgrid(x,y)
Z = np.zeros(np.shape(X))
for (i,j),_ in np.ndenumerate(Z):
Z[i,j] = d([X[i,j],Y[i,j]])
#Z=d([X,Y]) #this fails
解决方案
我们可以利用broadcasting
直接使用1D
版本,从而提高内存效率,并给自己一个矢量化的单线,就像这样 -
Z = np.sqrt((x[:,None] - points[:,0])**2 + (y[:,None,None] - points[:,1])**2).sum(2)
发布样本数据的时间 -
In [80]: %%timeit
...: X, Y = np.meshgrid(x,y)
...: Z = np.zeros(np.shape(X))
...: for (i,j),_ in np.ndenumerate(Z):
...: Z[i,j] = d([X[i,j],Y[i,j]])
10 loops, best of 3: 101 ms per loop
In [81]: %timeit ((x[:,None] - points[:,0])**2 + (y[:,None,None] - points[:,1])**2).sum(2)
1000 loops, best of 3: 246 µs per loop
400x
那里加速!
推荐阅读
- mongodb - 单个 MongoDB 模式中的多个引用
- msbuild - 从 MSBuild 发布命令中删除版本
- c# - 如何使用 Mock.Of<> 语法模拟在构造函数中具有参数的类?
- reactjs - Android TV中焦点可触摸元素的事件句柄
- tomcat - Tomcat 8.5.23 是否泄漏套接字?
- google-cloud-platform - Dialogflow 代理突然停止响应
- javascript - 使正确的 div 响应
- c# - “只读”是否提供了“{get;}”在声明只读属性时不提供的东西?
- r - DT::datatable 中某些复选框的预选无法正常工作,因为它们仍处于未选中状态
- mysql - 在 MySQL 中优化依赖子查询的索引