我需要使用NumPy实现以下功能 -
其中F_l(x)
是N
我需要计算的数组数,这些数组依赖于数组G(x)
,我得到了,A_j
是{{} 1}}也给出了系数。我想在NumPy中实现它,因为我必须为我的程序的每次迭代计算N
。这样做的虚拟方法是for for循环和ifs:
F_l(x)
至于循环和if语句相对较慢,我正在寻找一种NumPy诙谐的方式来做同样的事情。有人有想法吗?
答案 0 :(得分:2)
本文中列出了一个矢量化解决方案,根据所涉及的计算,在将输入数组的维度扩展到具有NumPy's powerful broadcasting feature的3D和4D情况后,大量使用np.newaxis/None
。这是实施 -
# Get size of A
N = A.size
# Perform "(G - A[l])/(G + A[j]))" in a vectorized manner
p1 = (G - A[:,None,None,None])/(G + A[:,None,None])
# Perform "((A[l] - A[j])/(A[l] + A[j]))" in a vectorized manner
p2 = ((A[:,None] - A)/(A[:,None] + A))
# Elementwise multiplications between the previously calculated parts
p3 = p1*p2[...,None,None]
# Set the escaped portion "j != l" output as "G/A[l]"
p3[np.eye(N,dtype=bool)] = G/A[:,None,None]
Fout = p3.prod(1)
# If you need separate arrays just like in the question, split it
Fout_split = np.array_split(Fout,N)
示例运行 -
In [284]: # Original inputs
...: A = np.arange(1.,5.,1)
...: G = np.array([[1.,2.],[3.,4.]])
...:
In [285]: calcF(G,A)
Out[285]:
[array([[-0. , -0.00166667],
[-0.01142857, -0.03214286]]), array([[-0.00027778, 0. ],
[ 0.00019841, 0.00126984]]), array([[ 1.26984127e-03, 1.32275132e-04],
[ -0.00000000e+00, -7.93650794e-05]]), array([[-0.00803571, -0.00190476],
[-0.00017857, 0. ]])]
In [286]: vectorized_calcF(G,A) # Posted solution
Out[286]:
[array([[[-0. , -0.00166667],
[-0.01142857, -0.03214286]]]), array([[[-0.00027778, 0. ],
[ 0.00019841, 0.00126984]]]), array([[[ 1.26984127e-03, 1.32275132e-04],
[ -0.00000000e+00, -7.93650794e-05]]]), array([[[-0.00803571, -0.00190476],
[-0.00017857, 0. ]]])]
运行时测试 -
In [289]: # Larger inputs
...: A = np.random.randint(1,500,(400))
...: G = np.random.randint(1,400,(20,20))
...:
In [290]: %timeit calcF(G,A)
1 loops, best of 3: 4.46 s per loop
In [291]: %timeit vectorized_calcF(G,A) # Posted solution
1 loops, best of 3: 1.87 s per loop
Vectorization
可以考虑的事项的快速检查清单 -
关于扩展维度的想法:要为输入数组扩展维度,以便新维度保留在嵌套循环中迭代生成的结果。
从哪里开始向量化?从最深处(代码迭代最多的循环)计算阶段开始,看看如何扩展输入并引入相关计算。请仔细跟踪所涉及的迭代器并相应地扩展尺寸。向外移动到外部循环,直到您对完成的矢量化感到满意。
如何处理条件语句?对于简单的情况,暴力计算所有内容并查看以后如何处理IF / ELSE部分。这将是高度针对具体情况的。
是否存在依赖项?如果是,请查看是否可以跟踪和实施相关性。这可以形成另一个讨论主题,但这里是few examples
我自己参与其中。