- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
因此,我正在试验在 numba
中结合向量化和由 @njit
提供支持的 for 循环的性能提升(我目前使用的是 numba 0.45.1
)。令人失望的是,我发现它实际上比我代码中的纯嵌套循环实现要慢。
这是我的代码:
import numpy as np
from numba import njit
@njit
def func3(arr_in, win_arr):
n = arr_in.shape[0]
win_len = len(win_arr)
result = np.full((n, win_len), np.nan)
alpha_arr = 2 / (win_arr + 1)
e = np.full(win_len, arr_in[0])
w = np.ones(win_len)
two_index = np.nonzero(win_arr <= 2)[0][-1]+1
result[0, :two_index] = arr_in[0]
for i in range(1, n):
w = w + (1-alpha_arr)**i
e = e*(1-alpha_arr) + arr_in[i]
result[i,:] = e /w
return result
@njit
def func4(arr_in, win_arr):
n = arr_in.shape[0]
win_len = len(win_arr)
result = np.full((n, win_len), np.nan)
alpha_arr = 2 / (win_arr + 1)
e = np.full(win_len, arr_in[0])
w = np.ones(win_len)
two_index = np.nonzero(win_arr <= 2)[0][-1]+1
result[0, :two_index] = arr_in[0]
for i in range(1, n):
for col in range(len(win_arr)):
w[col] = w[col] + (1-alpha_arr[col])**i
e[col] = e[col]*(1-alpha_arr[col]) + arr_in[i]
result[i,col] = e[col] /w[col]
return result
if __name__ == '__main__':
np.random.seed(0)
data_size = 200000
winarr_size = 1000
data = np.random.uniform(0,1000, size = data_size)+29000
win_array = np.arange(1, winarr_size+1)
abc_test3= func3(data, win_array)
abc_test4= func4(data, win_array)
print(np.allclose(abc_test3, abc_test4, equal_nan = True))
我使用以下配置对这两个函数进行了基准测试:
(data_size,winarr_size)
= (200000,100), (200000,200),(200000,1000), (200000,2000), (20000,10000), ( 2000,100000)
.
并且发现纯嵌套 for 循环实现 (func4
) 始终比 for 循环与矢量化混合实现 ( func3
).
我的问题如下:
1)为了进一步提高代码的速度,需要更改什么?
2) 为什么函数的向量化版本的计算时间随着 win_arr
的大小线性增长?我认为矢量化应该做到这一点,以便无论矢量有多大/多小,操作速度都是恒定的,但显然这在这种情况下不成立。
3) 是否存在矢量化运算的计算时间仍会随着输入大小线性增长的一般条件?
最佳答案
您似乎误解了“矢量化”的含义。矢量化意味着您编写的代码在数组上进行操作,就好像它们是标量一样——但这只是代码的样子,与性能无关。
在 Python/NumPy 世界中,矢量化还意味着与循环代码相比,矢量化操作中循环的开销(通常)很多较小。然而,矢量化代码仍然必须执行循环(即使它隐藏在库中)!
此外,如果您使用 numba 编写循环,numba 将对其进行编译并创建执行速度(通常)与矢量化 NumPy 代码一样快的代码。这意味着在 numba 函数内部,矢量化代码和非矢量化代码之间没有显着的性能差异。
所以这应该回答你的问题:
2) why is it that the computation time of the vectorized version of the function grows linearly with the size of the win_arr? I thought the vectorization should make it so that the operation speed is constant no matter how big/small the vector is, but apparently this does not hold true in this case.
它是线性增长的,因为它仍然需要迭代。在矢量化代码中,循环只是隐藏在库例程中。
3) Are there any general conditions under which the computation time of the vectorized operation will still grow linearly with the input size?
没有。
您还询问了可以做些什么来让它更快。
评论已经提到你可以将它并行化:
import numpy as np
import numba as nb
@nb.njit(parallel=True)
def func6(arr_in, win_arr):
n = arr_in.shape[0]
win_len = len(win_arr)
result = np.full((n, win_len), np.nan)
alpha_arr = 2 / (win_arr + 1)
e = np.full(win_len, arr_in[0])
w = np.ones(win_len)
two_index = np.nonzero(win_arr <= 2)[0][-1]+1
result[0, :two_index] = arr_in[0]
for i in range(1, n):
for col in nb.prange(len(win_arr)):
w[col] = w[col] + (1-alpha_arr[col])**i
e[col] = e[col] * (1-alpha_arr[col]) + arr_in[i]
result[i,col] = e[col] /w[col]
return result
这使代码在我的机器(4 核)上运行得更快一些。
但是,还有一个问题是您的算法可能在数值上不稳定。当您将 (1-alpha_arr[col])**i
提高到十万次方时,它会在某个时刻下溢:
>>> alpha = 0.01
>>> for i in [1, 10, 100, 1_000, 10_000, 50_000, 100_000, 200_000]:
... print((1-alpha)**i)
0.99
0.9043820750088044
0.3660323412732292
4.317124741065786e-05
2.2487748498162805e-44
5.750821364590612e-219
0.0 # <-- underflow
0.0
关于python - 循环中的矢量化比 numba jitted 函数中的嵌套循环慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57917429/
我正在尝试将字符串列表转换为字符向量的向量: import collection.breakOut def stringsToCharVectors(xs: List[String]) = x
我正在尝试使用 Pytorch 通过 2D 向量(嘈杂语音帧序列)的回归来预测 1D 向量(干净语音数据帧) data) - 之前已经完成过。帧序列为帧提供时间上下文,以更准确地预测干净帧。这些向量可
在尝试构建时,我收到此错误: Operator '+=' is ambiguous on operands of type 'Vector3' and 'Vector2' 这是问题出处的脚本代码: u
是否存在实现 FIFO 意义上的循环数组或向量的 R 包? 假设我们有这个数组: 2 4 7 1 当在位置 1 插入一个新的观察值(比如 3)时,我希望第 n 个元素被第 n-1 个元素替换: 3 2
我在游戏中有两个对象,为此可以将其视为 2d 平面上的点,但我使用 Vector3s,因为游戏本身是 3d。 我有一个游戏相机,我想将其与两个物体垂直(也在平面上)对齐,以便它们都在相机的视野中。由于
我做了一个Telegram robot ,它的工作之一是从音频文件创建样本。现在对于发送给它的大多数音频,样本都非常好;像这样: 但是,对于一些音频,样本看起来有点奇怪: 如您所见,此文件中的波形未显
由于对 JavaScript 非常陌生,我在使用 JQuery VectorMaps 时遇到了以下问题: 当我用这种语法突出显示一个国家时,一切都很完美: jQuery('#vmap').vector
我正在使用 ChartJS 在我的网站中包含一些 map ,但 ChartJS 库没有我想要的 map 。 我想知道这种类型的矢量 map 是否很容易在网上免费找到,还是必须从头开始构建? Chart
我需要创建一个函数。在此范围内,我需要发生以下事情: List 1: '(a 5 6) List 2: '(c 8 10) List 3: '(d 4 9) 以上是列表。我需要忽略每个列表的第一列(这
我在地球表面有一个点,我正在将其从地球中心转换为向量。 我有一个以度数表示的真北航向,描述了该点将在地球表面行进的路径。 我需要计算一个向量,该向量垂直于该点沿地球表面的路径所创建的平面。 我尝试
大家好,这是我的 JavaScript 代码,用于为矢量 map 制作 ip 标记以显示在线 ip.. 所有 ips 都有 3 个不同的端口,例如:ip1:1020 或 ip2:5050 或 ip3:
我正在使用 Three.js 透视相机,我需要了解相机所注视的点。 如何使用相机的矩阵/旋转向量计算它? 最佳答案 相机向下看它的内部负 z 轴。所以选择相机负 z 轴上的任意点,如下所示: var
重要提示:请注意这个问题是关于 VECTOR map 的。不是高度图。 我正在尝试在 Scenekit 中实现 Vector 位移,如 apple 演示文稿中所述: https://www.youtu
我正在处理一个稳定增长的语料库。我使用用 Python 实现的 Doc2Vec 来训练我的文档向量。 是否可以更新文档向量? 我想使用文档向量进行文档推荐。 最佳答案 单个向量可以更新,但是 gens
我正在努力寻找一种比较(测量)两个不同信号之间相似性的好方法。我不想找出一个信号到另一个信号的时间延迟,但我想看看它们之间有何相似之处。例如,我有以下两个信号,比如说 s1 ans s2。这两个信号看
我想绘制 y 与 x 线,然后在它上面我想绘制向量。我可以使用 matplotlib 的 plot 和 quiver 函数来做到这一点。但是,矢量将始终绘制在线的后面,而不是在线的顶部。也就是说,线将
包含复数的向量 a 的大小为 N×1。任务是找到乘法a * a^HA (N-by-N) >,其中 H 是 Hermitian 算子(共轭转置),因此矩阵 A 是 Hermitian。 有没有比 O(N
三天来,我一直在努力从我的响应中获取复杂类型(列表),但总是收到 ClassCastException D/SOAPEnvelope(1552): Error: java.lang.ClassCast
在我的 android 项目中,我想要离线 map 。使用图 block ,我的 map 占用 500 MB 的空间,我还想在 map 上离线搜索地址。我认为减小尺寸并使搜索成为可能的唯一方法是矢量
什么是 Android Compose 方法来平铺图像以用小图案填充我的背景? 没有旋转的位图的天真方法可能是这样的: @Composable fun TileImage() { val pa
我是一名优秀的程序员,十分优秀!