NumPy中序列的乘积 [英] Product of a sequence in NumPy

查看:88
本文介绍了NumPy中序列的乘积的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用NumPy实现以下功能-





其中 F_l(x)是我需要计算的 N 个数组的数量,它们是相关的在给出的数组 G(x)上,和 A_j N 系数也已给出。我想在NumPy中实现它,因为我必须为程序的每次迭代计算 F_l(x)。虚假的方法是通过for循环和ifs:

  import numpy as np 
A = np.arange (1.,5.,1)
G = np.array([[1.,2。],[3.,4。]])

def calcF(G, A):
N = A.size
打印A
打印N
F = []
for l in range(N):
F。 append(G / A [l])
print F [l]
对于范围(N)中的j:如果j!= l:
F [l] * = (((G-A [l])/(G + A [j]))*(((A [l]-A [j])/(A [l] + A [j])))
返回F

F = calcF(G,A)
打印F



<对于循环,如果语句相对较慢,我正在寻找一种NumPy机智的方法来做同样的事情。有人有主意吗?

解决方案

本文中列出的是矢量化解决方案,大量使用了 NumPy强大的广播功能,使用 np.newaxis / None 根据所涉及的计算在各个位置。这是实现-

 #获取A 
的大小N = A.size

#执行 (G-A [l])/(G + A [j]))。以矢量化方式
p1 =(G-A [:,None,None,None])/(G + A [:,None,None])

#执行``( (A [l]-A [j])/(A [l] + A [j]))以矢量化方式
p2 =(((A [:,None]-A)/(A [:,None] + A))

#先前计算的部分$之间的元素乘法b $ b p3 = p1 * p2 [...,None,None]

#设置转义部分 j!= l。输出为 G / A [l];
p3 [np.eye(N,dtype = bool)] = G / A [:,None,None]
Fout = p3.prod(1)

#如果您需要像问题中一样的单独数组,将其拆分
Fout_split = np.array_split(Fout,N)

示例运行-

 在[284]中:#原始输入
...: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] ]),数组([[--0.00027778,0.],
[0.00019841,0.00126984]]),数组([[1.26984127e-03,1.32275132e-04],
[-0.00000000e + 00,-7.93650794e-05]])),数组([[--0.00803571,-0.00190476],
[-0.00017857,0.]]))]

在[286]中:vectorized_calcF (G,A)#发表的解决方案
Out [286]:
[array([[[-0。,-0.00166667],
[-0.01142857,-0.03214286]]])),数组([[[--0.00027778,0.],
[0.00019841,0.0 0126984]]]))数组([[[1.26984127e-03,1.32275132e-04],
[-0.00000000e + 00,-7.93650794e-05]]]))数组([[[--0.00803571 ,-0.00190476],
[-0.00017857,0.]]])]]

运行时测试-

 在[289]中:#较大的输入
...:A = np.random.randint(1,500,(400))
...:G = np.random.randint(1,400,(20,20))
...:

在[290]中:%timeit calcF(G,A )
1循环,最佳3:每个循环4.46 s

在[291]中:%timeit vectorized_calcF(G,A)#发表解决方案
1循环,最佳3 :每个循环1.87 s




使用NumPy / MATLAB进行矢量化:通用方法


感觉就像我在一般方法上投入两美分一样,我认为其他人在尝试向量化代码时会遵循类似的策略,尤其是在像NumPy或MATLAB这样的高级平台中。因此,这里有一个快速检查清单,可以考虑 向量化 -


有关扩展尺寸的想法:要扩展输入数组的尺寸,以便新尺寸保存结果


从哪里开始矢量化?从最深的地方开始(那个循环在代码中迭代最多的地方) )计算阶段,并查看如何扩展输入并引入相关计算。请仔细跟踪所涉及的迭代器并相应地扩展尺寸。

如何处理条件语句?对于简单的情况,蛮力计算所有内容并看看以后如何处理IF / ELSE部件。


是否存在依赖项?如果是,请查看是否可以跟踪并实现依赖项。这可能会形成另一个讨论的主题,但这是 几个例子 我参与其中。


I need to implement this following function with NumPy -

where F_l(x) are N number of arrays that I need to calculate, which are dependent on an array G(x), that I am given, and A_j are N coefficients that are also given. I would like to implement it in NumPy as I would have to calculate F_l(x) for every iteration of my program. The dummy way to do this is by for loops and ifs:

import numpy as np
A = np.arange(1.,5.,1)
G = np.array([[1.,2.],[3.,4.]])

def calcF(G,A):
    N = A.size
    print A
    print N
    F = []
    for l in range(N):
        F.append(G/A[l])
        print F[l]
        for j in range(N):
            if j != l:
                F[l]*=((G - A[l])/(G + A[j]))*((A[l] - A[j])/(A[l] + A[j]))
    return F

F= calcF(G,A)
print F

As for loops and if statements are relatively slow, I am looking for a NumPy witty way to do the same thing. Anyone has an idea?

解决方案

Listed in this post is a vectorized solution making heavy usage of NumPy's powerful broadcasting feature after extending dimensions of input arrays to 3D and 4D cases with np.newaxis/None at various places according to the computation involved. Here's the implementation -

# 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)

Sample run -

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.        ]]])]

Runtime test -

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 with NumPy/MATLAB : General approach

Felt like I could throw in my two cents on my general approach and I would think others follow similar strategies when trying to vectorize codes, especially in a high level platform like NumPy or MATLAB. So, here's a quick check-list of things that could be considered for Vectorization -

Idea about extending the dimensions : Dimensions are to be extended for the input arrays such that the new dimensions hold results that would have otherwise gotten generated iteratively within the nested loops.

Where to start vectorizing from? Start from the deepest (that loop where the code is iterating the most) stage of computation and see how inputs could be extended and the relevant computation could be brought in. Take good care of tracing the iterators involved and extend dimensions accordingly. Move outwards onto outer loops, until you are satisfied with the vectorization done.

How to take care of conditional statements? For simple cases, brute force compute everything and see how the IF/ELSE parts could be taken care of later on. This would be highly context specific.

Are there dependencies? If so, see if the dependencies could be traced and implemented accordingly. This could form another topic for discussion, but here are few examples I got myself involved with.

这篇关于NumPy中序列的乘积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆